通过sqlalchemy关系通过backref属性获取父母子女会导致不必要的刷新

时间:2013-11-07 19:54:35

标签: python sqlite sqlalchemy

我有这样的sqlalchemy关系(为简单而修剪):

class Parent(Base):
  __tablename__ = 'Parent'
  name = Column(String, nullable=False)
  def __init__(self, name)
    self.name = name

class Child(Base):
  __tablename__ = 'Child'
    name = Column(String, nullable=False)
    parent = relationship(Parent, backref=backref('children')
  def __init__(self, name, parent)
    self.name = name
    self.parent = parent

在我的对象工作的同时:

parent = Parent("my parent")
db_session.add(parent) # must be done for other reasons not relevant to the issue.
child = Child("my child", parent)

到目前为止一切顺利。 但是在我执行以下操作之前,我得到了一个DB刷新:

children = parent.children # using the backref causes a flush

可以通过更改我定义backref / relationship的方式来避免这种情况吗?

2 个答案:

答案 0 :(得分:4)

使用Session.no_autoflush上下文管理器应该以安全的方式实现您想要的目标:

with session.no_autoflush:    
    parent = Parent("my parent")
    db_session.add(parent) 
    child = Child("my child", parent)

答案 1 :(得分:0)

我不是SQLAlchemy专家,但看起来SQLAlchemy无法安全地填充parent.children集合,直到父和子都被刷新,因为用于他们关系的主键和外键是未定义的,直到发生。也许它甚至需要一个查询,因为它无法事先知道关系所需的所有对象是否都在当前会话中。

我没有看到任何解决方案,坦率地说,我不认为这是一个问题。你的案子闻起来很像过早的优化。

无论如何,我猜您可以在离开此点后设置session.autoflush = False并返回True来禁用会话中的autoflush。也许它有效,但你可能遇到意想不到的情况。