是否可以在模型中填充SQLalchemy外键并使其加载相关对象

时间:2016-11-22 15:01:13

标签: python sqlalchemy

在SQLAlchemy中,我有一个 transactionlog 模型,它有一个相关的 成员 。此关系由transactionlog表中的 tlog_ppl_id 列定义,该列引用 people 表中的 ppl_id 列( people < / em> table包含成员)。

假设我有一个新的Transactionlog对象T. 如果我加载一个成员对象(让我们称之为M),并设置T.mem​​ber = M,我可以访问T.mem​​ber并返回我的链接成员。

我想要做的是拥有我的新事务日志SQLAlchemy对象T,并使用有效的ppl_id填充tlog_ppl_id属性。 在我这样做之后,我想访问T.mem​​ber,并让SQLAlchemy从数据库加载相关的人员记录。但它没有这样做,它返回

所以我想知道是否有可能让SQLAlchemy用特定的指令加载相关的对象,如果我只填充对象的外键列?

测试此代码的代码:

def test():
    from app.models.data import Transactionlog
    T = Transactionlog()
    T.tlog_ppl_id = '2433A992-B8C7-4780-91DE-67D12C517C55'
    print(T.member)
    return ""

模型中的代码:

class Transactionlog(transactionlog):
    """
    Transactionlog model class.
    """

    member = relationship("People", backref=backref('transactions'))

我在下面的Python 3.5.1上使用SQLalchemy 1.0.14(不使用flask-sqlalchemy)

1 个答案:

答案 0 :(得分:0)

如果我理解正确,那么你可能正在寻找load_on_pending,尽管不鼓励使用它:

  

当正常使用ORM时,load_on_pending标志不会改善行为 - 对象引用应该在对象级别而不是在外键级别构造,以便它们在刷新之前以普通方式存在收益。此标志不适用于一般用途。

请注意,在您的test函数中,新创建的T实例在尝试打印相关People实例之前未添加到会话中,因此根本无法执行任何操作加载(除非某些魔法正在运行,并且所有新模型实例都被添加到某个默认会话中)。

这里有一个关于如何使用load_on_pending选项的小演示,不过我觉得你应该只使用实例对象而不是外键:

In [8]: class A(Base):
   ...:     __tablename__ = 'a'
   ...:     a_id = Column(Integer, primary_key=True)

In [9]: class B(Base):
   ...:     __tablename__ = 'b'
   ...:     b_id = Column(Integer, primary_key=True, autoincrement=True)
   ...:     a_id = Column(Integer, ForeignKey('a.a_id'))
   ...:     a = relationship('A', load_on_pending=True)

In [10]: class C(Base):
    ...:     __tablename__ = 'c'
    ...:     C_id = Column(Integer, primary_key=True, autoincrement=True)
    ...:     a_id = Column(Integer, ForeignKey('a.a_id'))
    ...:     a = relationship('A')

In [16]: session.add(A(a_id=1))

In [17]: session.commit()

In [18]: b = B()

In [19]: session.add(b)

In [20]: b.a_id = 1

In [21]: b.a
Out[21]: <__main__.A at 0x7ff32388ab70>

In [22]: session.rollback()

In [23]: c = C()

In [25]: session.add(c)

In [26]: c.a_id = 1

In [27]: c.a

In [28]: session.commit()

In [29]: c.a
Out[29]: <__main__.A at 0x7ff32388ab70>

但是,如前所述,推荐的方法是使用实​​例,而不是外键:

# Will look the instance up in the session's identity map, if present
T.member = session.query(People).get('2433...')

我认为Zen of Python适用于这种情况:

  

明确比隐含更好。

即。显式查询待相关对象,而不是在设置外键后依赖隐式查找。