我试图找出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
这是预期的行为吗?如果是这样,这必须是开发人员头上的一个巨大的危险信号。当我们从DB检索记录作为声明性模型类的实例时,将填充record.one和record.one_id,但是当我们创建新记录时,情况并非如此!
答案 0 :(得分:4)
这是标准行为。 SQLAlchemy不会在提交之前根据其他更改反映外键更改或关系更改。如果您想在设置另一个属性时设置该属性,则可以使用Attribute Set事件。
通常鼓励您使用关系并忽略外键,因为SQLAlchemy在设置关系时会在后台执行很多不错的“魔术”。如果您希望外键执行相同的魔术,请参阅Expire Relationship on FK Change食谱。
现在这只是我的观点,但这不是一个“红旗”。您应该构建程序,以避免在新实例或更新实例与持久实例之间进行比较。