在SQLAlchemy中,我有一个 transactionlog 模型,它有一个相关的 成员 。此关系由transactionlog表中的 tlog_ppl_id 列定义,该列引用 people 表中的 ppl_id 列( people < / em> table包含成员)。
假设我有一个新的Transactionlog对象T. 如果我加载一个成员对象(让我们称之为M),并设置T.member = M,我可以访问T.member并返回我的链接成员。
我想要做的是拥有我的新事务日志SQLAlchemy对象T,并使用有效的ppl_id填充tlog_ppl_id属性。 在我这样做之后,我想访问T.member,并让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)
答案 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适用于这种情况:
明确比隐含更好。
即。显式查询待相关对象,而不是在设置外键后依赖隐式查找。