in session.commit, keep flushing until session is clean

Issue #2566 resolved
Mike Bayer repo owner created an issue
from sqlalchemy import event
from sqlalchemy.engine import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship, scoped_session, sessionmaker
from sqlalchemy.schema import Column, ForeignKey
from sqlalchemy.types import Integer, Text

Base = declarative_base()

engine = create_engine('sqlite://', echo=True)

Session = scoped_session(sessionmaker(
    autoflush=False,
    autocommit=False,
))

Session.configure(bind=engine)

class Ticket(Base):
    __tablename__ = 'tickets'

    id = Column(Integer, primary_key=True)
    description = Column(Text, nullable=False)

class Notification(Base):
    __tablename__ = 'notifications'

    id = Column(Integer, primary_key=True)
    ticket_id = Column(Integer, ForeignKey('tickets.id'), nullable=False)
    ticket = relationship('Ticket', backref='notifications')
    content = Column(Text, nullable=False)

def send_notification(session, flush_context):
    for instance in session.new:
        if isinstance(instance, Ticket):
            Notification(
                ticket=instance,
                content='Ticket %d created' % instance.id,
            )
            # No flush or commit!

event.listen(Session, 'after_flush', send_notification)

Base.metadata.create_all(engine)

ticket = Ticket(description='test')
Session.add(ticket)
Session.commit() # commits twice !!

patch:

diff -r 062f0a202af1185a21b94f33cb7af92cffacfd15 lib/sqlalchemy/orm/session.py
--- a/lib/sqlalchemy/orm/session.py Fri Sep 14 21:58:19 2012 -0400
+++ b/lib/sqlalchemy/orm/session.py Fri Sep 14 22:21:40 2012 -0400
@@ -291,7 +291,8 @@
                 subtransaction.commit()

         if not self.session._flushing:
-            self.session.flush()
+            while not self.session._is_clean():
+                self.session.flush()

         if self._parent is None and self.session.twophase:
             try:
      except:

Comments (2)

  1. Log in to comment