feat: add PostgreSQL database backend support
Add multi-database support allowing selection between SQL Server and PostgreSQL via database.active config. Changes include dialect-aware SQL generation, cross-database timestamp functions, PostgreSQL connection URL builder, and psycopg dependency. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
from typing import Literal
|
||||
from sqlalchemy.engine import URL
|
||||
from pydantic import BaseModel, Field
|
||||
from pydantic import BaseModel
|
||||
from pydantic_yaml import parse_yaml_raw_as
|
||||
|
||||
|
||||
@@ -16,9 +16,20 @@ class SqlServerConfig(BaseModel):
|
||||
trust_server_certificate: str = "yes"
|
||||
|
||||
|
||||
class PostgreSqlConfig(BaseModel):
|
||||
"""PostgreSQL 连接配置"""
|
||||
host: str
|
||||
port: int = 5432
|
||||
database: str
|
||||
username: str
|
||||
password: str
|
||||
|
||||
|
||||
class DatabaseConfig(BaseModel):
|
||||
"""数据库配置"""
|
||||
active: Literal["sql_server", "postgresql"] = "sql_server"
|
||||
sql_server: SqlServerConfig
|
||||
postgresql: PostgreSqlConfig | None = None
|
||||
|
||||
|
||||
class Settings(BaseModel):
|
||||
@@ -28,6 +39,11 @@ class Settings(BaseModel):
|
||||
@property
|
||||
def database_url(self) -> URL:
|
||||
"""构建数据库连接 URL"""
|
||||
if self.database.active == "postgresql":
|
||||
return self._postgresql_url()
|
||||
return self._sql_server_url()
|
||||
|
||||
def _sql_server_url(self) -> URL:
|
||||
conf = self.database.sql_server
|
||||
return URL.create(
|
||||
"mssql+pyodbc",
|
||||
@@ -42,6 +58,19 @@ class Settings(BaseModel):
|
||||
},
|
||||
)
|
||||
|
||||
def _postgresql_url(self) -> URL:
|
||||
conf = self.database.postgresql
|
||||
if conf is None:
|
||||
raise ValueError("已选择 postgresql,但未配置 database.postgresql")
|
||||
return URL.create(
|
||||
"postgresql+psycopg",
|
||||
username=conf.username,
|
||||
password=conf.password,
|
||||
host=conf.host,
|
||||
port=conf.port,
|
||||
database=conf.database,
|
||||
)
|
||||
|
||||
|
||||
def load_settings(config_path: str = "config/settings.yaml") -> Settings:
|
||||
"""加载 YAML 配置文件"""
|
||||
|
||||
Reference in New Issue
Block a user