You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用SQLAlchemy 1.4映射带UNIQUEIDENTIFIER主键的MS SQL Server表

问题:SQLAlchemy 1.4映射MS SQL Server UNIQUEIDENTIFIER主键表失败

使用SQLAlchemy 1.4映射MS SQL Server中主键为UNIQUEIDENTIFIER类型的表时遇到一系列问题:

  • 最初尝试用sqlalchemy.String映射,报错无法自增该类型;
  • 改用sqlalchemy.dialects.mssql.UNIQUEIDENTIFIER但未设置主键,触发主键组装错误:
class Result(Base):
    __tablename__ = os.environ["RESULT_TABLE_NAME"]
    __table_args__ = {"schema": "myschema"}
    id = Column(UNIQUEIDENTIFIER)

报错:sqlalchemy.exc.ArgumentError: Mapper mapped class Result->DT_ODS_RESULT could not assemble any primary key columns for mapped table 'DT_ODS_RESULT'

  • 添加primary_key=True后,插入数据时报主键为NULL:
class Result(Base):
    __tablename__ = os.environ["RESULT_TABLE_NAME"]
    __table_args__ = {"schema": "SIDODS"}
    id = Column(UNIQUEIDENTIFIER, primary_key=True)

报错:sqlalchemy.orm.exc.FlushError: Instance <Result at 0x7fbf9ab99d60> has a NULL identity key. If this is an auto-generated value, check that the database table allows generation of new primary key values, and that the mapped Column object is configured to expect these generated values. Ensure also that this flush() is not occurring at an inappropriate time, such as within a load() event.

数据库表已提前设置主键默认值:

ALTER TABLE [SIDODS].[DT_ODS_RESULT] ADD  DEFAULT (newid()) FOR [ID]

插入数据的代码如下:

r = Result(
    query_id=query_id,
    trigger_id=trigger_id,
    insertion_datetime=get_datetime_at_timezone()
)
session.add(r)
session.commit()
解决方案

要让SQLAlchemy正确识别数据库端生成的UNIQUEIDENTIFIER主键,需在列定义中添加server_default参数,显式告知SQLAlchemy该字段值由数据库服务器生成:

  1. 导入依赖:
from sqlalchemy import text
from sqlalchemy.dialects.mssql import UNIQUEIDENTIFIER
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()
  1. 正确定义模型类:
class Result(Base):
    __tablename__ = os.environ["RESULT_TABLE_NAME"]
    __table_args__ = {"schema": "SIDODS"}

    id = Column(UNIQUEIDENTIFIER, primary_key=True, server_default=text("newid()"))
    # 其他字段按实际表结构定义
    query_id = Column(...)
    trigger_id = Column(...)
    insertion_datetime = Column(...)

关键说明

虽然数据库表已配置默认值,但SQLAlchemy需要明确感知该字段的生成逻辑。通过server_default=text("newid()")配置后:

  • 插入数据时,SQLAlchemy不会向该字段传递NULL值,而是交由数据库执行newid()生成主键;
  • 会话提交后,SQLAlchemy会自动将数据库生成的ID同步到模型实例中。

此时原有的插入代码无需修改,即可实现无需手动指定ID的自动插入。

内容的提问来源于stack exchange,提问作者Itération 122442

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 01:45:30