使用SQLAlchemy插入含ForeignKey的记录时,为何ForeignKey会自动递增?
嘿,我来帮你分析下这个问题——你遇到的ForeignKey字段自动递增情况,根源出在子类Manager的字段定义和SQLAlchemy继承配置的细节上,咱们一步步拆解:
先看你代码里的Manager类定义:
class Manager(Employee): __tablename__ = 'manager' id = Column(Integer, ForeignKey('employee.sid'))
这里有两个关键疏漏导致了自动递增的问题:
子类外键未设为主键:在SQLAlchemy的Joined Table继承模式下(也就是你给子类单独设置
__tablename__的情况),子类表必须用关联父类主键的外键作为自己的主键。你现在的id字段只是外键,但没标记primary_key=True。SQLAlchemy对未显式配置的Integer字段,默认会开启autoincrement=True——哪怕它是外键,数据库也会把它当成自增列处理。缺少继承映射配置:子类需要明确告诉SQLAlchemy它的主键映射关系,要么在字段上设
primary_key=True,要么通过__mapper_args__指定,否则框架无法识别这个外键的真实作用,就会默认给它加上自增属性。
修改Manager类的定义,把id字段同时设为主键,并补充多态标识配置:
class Manager(Employee): __tablename__ = 'manager' # 同时标记为主键和外键 id = Column(Integer, ForeignKey('employee.sid'), primary_key=True) # 可以添加子类专属字段,比如部门信息 department = Column(String(50)) __mapper_args__ = { 'polymorphic_identity': 'manager' }
这样调整后,id字段会被SQLAlchemy正确识别为:既是manager表的主键,又是关联employee.sid的外键。当你插入Manager实例时,它会自动复用父类Employee生成的sid值作为manager.id的值,不会再自动生成新的递增数。
如果你本来想使用单表继承(所有子类数据都存在父类employee表中),那完全不需要给Manager设置__tablename__,这种情况下也不会出现额外的外键自增问题。但从你的代码结构来看,Joined Table继承应该是你的目标,所以上面的修复方案最贴合你的场景。
内容的提问来源于stack exchange,提问作者edgeidea

