Andrew
Andrew

Reputation: 674

Getting a parents children through a backref attribute via sqlalchemy relationship causes unnecessary flush

I have a sqlalchemy relationship like this (trimmed for simplicity):

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

While working while my objects i do:

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

So far so good. But prior to committing when I do the following I get a DB flush:

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

Can this be avoided by changing how I define the backref/relationship?

Upvotes: 5

Views: 1845

Answers (2)

benselme
benselme

Reputation: 3197

Using the Session.no_autoflush context manager should achieve what you want in a safe manner:

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

Upvotes: 4

Pedro Werneck
Pedro Werneck

Reputation: 41928

I'm no SQLAlchemy expert, but it looks like SQLAlchemy can't populate the parent.children collection safely until both parent and children are flushed, since the primary and foreign keys used for their relationship is undefined until that happens. Maybe it even needs a query, since it can't know beforehand if all objects required to the relationship are in the current session.

I don't see any solution to that, and frankly, I don't see it as a problem. Your case smells a lot like premature optimization.

Anyway, I guess you can disable autoflush on your session by setting session.autoflush = False and back to True after leaving this point. Maybe it works, but you may run into unexpected situations.

Upvotes: 0

Related Questions