使用Alembic+SQLModel生成迁移时为何会自动修改主键字段
问题原因解释
这个不是操作失误,是SQLModel和Alembic的元数据映射适配存在的已知行为:
- 你在Song模型中定义主键id的代码为
id: int = Field(default=None, primary_key=True, index=False),SQLModel内部会自动识别主键属性,在表创建时默认给主键加上非空、自增约束,这也是你第一次生成迁移后数据库id字段的实际属性。 - 但Alembic做自动迁移的字段差异比对时,会直接读取模型字段的显式定义:你写了
default=None且字段类型没有标记为Optional,Alembic会错误判定你要将id字段调整为允许为空,因此每次自动生成迁移都会额外生成修改id字段nullable属性的语句。
解决方案
有几种方式可以避免这个问题:
- 修正主键字段的写法:按照SQLModel官方推荐的主键定义方式修改id字段,将类型显式标记为Optional:
class Song(SongBase, table=True): id: Optional[int] = Field(default=None, primary_key=True)
修改后再生成迁移,Alembic就不会再判定id字段的nullable属性存在差异,不会生成多余的修改语句。
2. 添加Alembic比对过滤规则:在Alembic的env.py配置文件中添加自定义字段比对逻辑,直接忽略主键字段的nullable属性校验,避免生成无关语句。
3. 人工校验迁移文件:Alembic自动生成的迁移脚本本身就带有# ### commands auto generated by Alembic - please adjust! ###的提示,要求人工校验内容,每次生成后手动删除无关的主键修改语句即可,这个操作是可控的,不会带来额外风险。
生产环境适用性说明
SQLModel+Alembic的组合完全可以用于生产环境,上述问题只是框架适配层面的小问题,没有底层缺陷。只要遵循「自动生成迁移→人工校验调整→执行迁移」的流程,就能完全规避风险。
内容的提问来源于stack exchange,提问作者Trondh
相关产品推荐
相关产品推荐

