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:
@@ -20,7 +20,10 @@ class FinishedGoodsLocation(Base):
|
||||
zongpai_no: Mapped[str] = mapped_column(String(64), nullable=False)
|
||||
location_code: Mapped[str] = mapped_column(String(64), nullable=False)
|
||||
created_at: Mapped[datetime] = mapped_column(
|
||||
DateTime, nullable=False, server_default=func.getdate()
|
||||
DateTime,
|
||||
nullable=False,
|
||||
default=func.current_timestamp(),
|
||||
server_default=func.current_timestamp(),
|
||||
)
|
||||
|
||||
|
||||
@@ -36,7 +39,10 @@ class FinishedGoodsBox(Base):
|
||||
paichan_no: Mapped[str] = mapped_column(String(64), nullable=False)
|
||||
box_no: Mapped[int] = mapped_column(nullable=False)
|
||||
created_at: Mapped[datetime] = mapped_column(
|
||||
DateTime, nullable=False, server_default=func.getdate()
|
||||
DateTime,
|
||||
nullable=False,
|
||||
default=func.current_timestamp(),
|
||||
server_default=func.current_timestamp(),
|
||||
)
|
||||
|
||||
|
||||
@@ -53,5 +59,8 @@ class FinishedGoodsBoxItem(Base):
|
||||
zongpai_no: Mapped[str] = mapped_column(String(64), nullable=False)
|
||||
quantity: Mapped[float | None] = mapped_column(Numeric(18, 3), nullable=True)
|
||||
created_at: Mapped[datetime] = mapped_column(
|
||||
DateTime, nullable=False, server_default=func.getdate()
|
||||
DateTime,
|
||||
nullable=False,
|
||||
default=func.current_timestamp(),
|
||||
server_default=func.current_timestamp(),
|
||||
)
|
||||
|
||||
@@ -25,11 +25,7 @@ class DuplicateBoxItemError(Exception):
|
||||
|
||||
def query_erp_info(db: Session, zongpai_no: str) -> dict:
|
||||
"""从 ERP 视图查询总排号对应的排产号和数量。"""
|
||||
sql = text(
|
||||
"SELECT TOP 1 [总排号], [排产号], [数量] "
|
||||
"FROM [ERPAuto].[vw_productionContractData] "
|
||||
"WHERE [总排号] = :zongpai_no"
|
||||
)
|
||||
sql = text(_erp_info_sql(db))
|
||||
row = db.execute(sql, {"zongpai_no": zongpai_no}).fetchone()
|
||||
if not row:
|
||||
raise ZongpaiNotFoundError()
|
||||
@@ -40,6 +36,22 @@ def query_erp_info(db: Session, zongpai_no: str) -> dict:
|
||||
}
|
||||
|
||||
|
||||
def _erp_info_sql(db: Session) -> str:
|
||||
dialect_name = db.bind.dialect.name if db.bind is not None else ""
|
||||
if dialect_name == "postgresql":
|
||||
return (
|
||||
'SELECT "总排号", "排产号", "数量" '
|
||||
'FROM "ERPAuto"."vw_productionContractData" '
|
||||
'WHERE "总排号" = :zongpai_no '
|
||||
"LIMIT 1"
|
||||
)
|
||||
return (
|
||||
"SELECT TOP 1 [总排号], [排产号], [数量] "
|
||||
"FROM [ERPAuto].[vw_productionContractData] "
|
||||
"WHERE [总排号] = :zongpai_no"
|
||||
)
|
||||
|
||||
|
||||
def get_box_info(db: Session, zongpai_no: str) -> dict:
|
||||
"""获取装箱信息:排产号、数量、已有箱号明细。"""
|
||||
zongpai_no = zongpai_no.strip().upper()
|
||||
|
||||
Reference in New Issue
Block a user