我试图弄清楚SQLAlchemy处理外键的方式。
考虑以下模型:
class ModelOne(Base):
__tablename__ = 'model_one'
id = Column(Integer, primary_key=True)
...
class ModelTwo(Base):
__tablename__ = 'model_two'
id = Column(Integer, primary_key=True)
one_id = Column(Integer, ForeignKey('model_one.id'))
one = relationship('ModelOne')
我假设如果我们有两个这样的模型,那么SQLAlchemy将找出ModelTwo.one_id和ModelTwo.one引用的是同一数据库列。
创建ModelTwo记录时,我们可以使用ModelOne记录的数字ID或ModelOne实例来填充FK字段:
one = DBSession.query(ModelOne)....
two_a = ModelTwo(one_id=one.id)
two_b = ModelTwo(one=one)
这有效。
但这是一个扭曲:实例化ModelTwo实例后,根据我们初始化FK字段的方式,将立即不填充该字段的一个或另一个表示形式:
two_a.one is None # evaluates to True
two_b.one_id is None # evaluates to True
这是预期的行为吗?如果是这样,这对于开发人员来说必须是一个巨大的危险信号。当我们从数据库检索一个记录作为声明性模型类的实例时,将同时填充record.one和record.one_id,但是当我们创建新记录时,情况并非如此!
这是标准行为。在提交之前,SQLAlchemy不会反映基于其他更改的外键更改或关系更改。如果要在设置另一个属性时设置该属性,则可以使用Attribute Set事件。
通常建议您使用该关系并忽略外键,因为在设置关系时,SQLAlchemy将在后台执行很多不错的“魔术”操作。如果您希望外键执行相同的操作,请参见“更改FK时的过期关系”配方。
这只是我现在的意见,但这不是“危险信号”。您应该改用程序结构,以避免在新实例或更新实例与持久实例之间进行比较。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句