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

如何在SQLModel中动态设置含表名的SQL默认值?

解决方案

要实现动态将子类表名嵌入sequence_id的默认值,核心是利用declared_attr动态定义字段,而非静态声明——这样在子类继承时就能获取到当前子类的表名信息:

from sqlalchemy import Column, VARCHAR, text
from sqlalchemy.ext.declarative import declared_attr
from sqlmodel import SQLModel, Field, Optional
from uuid import UUID

class BaseModel(SQLModel):
    @declared_attr
    def __tablename__(cls) -> str:
        return cls.__name__

    guid: Optional[UUID] = Field(default=None, primary_key=True)

class SequencedBaseModel(BaseModel):
    @declared_attr
    def sequence_id(cls) -> str:
        # 直接通过cls获取子类的表名
        return Field(
            sa_column=Column(
                VARCHAR(50),
                server_default=text(f"SELECT '{cls.__tablename__}_' + convert(varchar(10), NEXT VALUE FOR dbo.sequence)")
            )
        )

# 定义Project表示例
class Project(SequencedBaseModel, table=True):
    name: str = Field(...)

关键细节说明

  • @declared_attr装饰sequence_id方法后,子类(如Project)继承时会触发该方法的执行,此时cls指向子类本身,能直接读取cls.__tablename__。
  • 生成的server_default会自动替换为子类的表名,比如Project类对应的默认值就是SELECT 'Project_' + convert(varchar(10), NEXT VALUE FOR dbo.sequence),最终生成Project_1、Project_2这类格式的序列值。
  • Alembic生成迁移脚本时,能正确识别每个子类的sequence_id列对应的默认值——因为declared_attr在模型构建阶段就完成了动态求值,Alembic可以拿到最终的列定义。

迁移脚本验证

运行alembic revision --autogenerate生成迁移时,Project表的sequence_id列默认值会被正确生成为:

server_default=sa.text("SELECT 'Project_' + convert(varchar(10), NEXT VALUE FOR dbo.sequence)")

内容的提问来源于stack exchange,提问作者Matthias Burger

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 01:27:07