【问题标题】:Why are not ForeignKey and RelationshipProperty attributes in SQLAlchemy automatically synchronized?为什么 SQLAlchemy 中的 ForeignKey 和 RelationshipProperty 属性没有自动同步?
【发布时间】:2014-09-01 09:00:59
【问题描述】:

我试图弄清楚 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 都将被填充,但是当我们创建新记录时,情况并非如此!

【问题讨论】:

    标签: python sqlalchemy foreign-key-relationship


    【解决方案1】:

    这是标准行为。 SQLAlchemy 在提交之前不会反映基于其他更改的外键更改或关系更改。如果您想在设置其他属性时设置属性,可以使用Attribute Set 事件。

    通常鼓励您使用关系并忽略外键,因为 SQLAlchemy 在设置关系时会在后台执行很多漂亮的“魔术”。如果您希望外键执行同样的魔法,请参阅Expire Relationship on FK Change 配方。

    这只是我现在的看法,但这不是“危险信号”。相反,您应该构建程序以避免在新的或更新的实例与持久实例之间进行比较。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-11-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-30
      • 1970-01-01
      • 1970-01-01
      • 2011-09-19
      相关资源
      最近更新 更多