Re: [sqlalchemy] Why ORM objects in a session expire immediately after a failure in flush?
On Thu, Jan 9, 2014 at 9:59 PM, Michael Bayer mike...@zzzcomputing.com wrote: I do notice that you’re catching an IntegrityError.The typical pattern when writing code that wants to catch these and then continue is to run the individual set of questionable operations within a SAVEPOINT, that is a begin_nested()/commit() block. Recent versions of SQLAlchemy have the behavior such that when a flush() exception rolls back the SAVEPOINT, objects that were not modified within the SAVEPOINT are not expired; only those objects that changed within the save point’s scope do. How recent does recent mean there? (just curious) -- You received this message because you are subscribed to the Google Groups sqlalchemy group. To unsubscribe from this group and stop receiving emails from it, send an email to sqlalchemy+unsubscr...@googlegroups.com. To post to this group, send email to sqlalchemy@googlegroups.com. Visit this group at http://groups.google.com/group/sqlalchemy. For more options, visit https://groups.google.com/groups/opt_out.
Re: [sqlalchemy] Why ORM objects in a session expire immediately after a failure in flush?
changelog in 0.8.0b1: http://docs.sqlalchemy.org/en/rel_0_9/changelog/changelog_08.html#change-1df6e3552ee895cd48952f95c0f0730a ticket: http://www.sqlalchemy.org/trac/ticket/2452 I wonder if offering that the automatic rollback() on flush() might be optionally disabled (which means, a corrupted flush is in danger of being committed if the user is not careful) would be a compromise for this behavior in the bigger sense. On Jan 10, 2014, at 8:41 AM, Claudio Freire klaussfre...@gmail.com wrote: On Thu, Jan 9, 2014 at 9:59 PM, Michael Bayer mike...@zzzcomputing.com wrote: I do notice that you’re catching an IntegrityError.The typical pattern when writing code that wants to catch these and then continue is to run the individual set of questionable operations within a SAVEPOINT, that is a begin_nested()/commit() block. Recent versions of SQLAlchemy have the behavior such that when a flush() exception rolls back the SAVEPOINT, objects that were not modified within the SAVEPOINT are not expired; only those objects that changed within the save point’s scope do. How recent does recent mean there? (just curious) -- You received this message because you are subscribed to the Google Groups sqlalchemy group. To unsubscribe from this group and stop receiving emails from it, send an email to sqlalchemy+unsubscr...@googlegroups.com. To post to this group, send email to sqlalchemy@googlegroups.com. Visit this group at http://groups.google.com/group/sqlalchemy. For more options, visit https://groups.google.com/groups/opt_out. signature.asc Description: Message signed with OpenPGP using GPGMail
[sqlalchemy] Why ORM objects in a session expire immediately after a failure in flush?
Hi, folks, I observed that it seems all ORM objects in a session will expire immediately if there is a failure in session.flush(). I was wondering what's the rationale behind this behavior. Following is an artificial web application code to illustrate the idea: def PUT(): # session and engine are all created with default parameter user = session.query(UserProfile).first() # deliberately tries to insert a Login record which has the same primary key as an existing one such that the later session.flush() will fail try: duplicated_login_record = Login(id=0, username=username:weikai) session.add(duplicated_login_record) session.flush() except IntegrityError: session.rollback() print user.id ... By turning on logging, I noticed the print user.id line always result in a new SELECT being issued to database, which is an indicator that somehow user object got expired after the failure in session.flush(). For some other good reason which I don't want to elaborate here, we really don't want to have an extra SELECT going to DB in the processing of one HTTP request. Therefore, I was just wondering why is this behavior and whether it can be turned off. -- You received this message because you are subscribed to the Google Groups sqlalchemy group. To unsubscribe from this group and stop receiving emails from it, send an email to sqlalchemy+unsubscr...@googlegroups.com. To post to this group, send email to sqlalchemy@googlegroups.com. Visit this group at http://groups.google.com/group/sqlalchemy. For more options, visit https://groups.google.com/groups/opt_out.
Re: [sqlalchemy] Why ORM objects in a session expire immediately after a failure in flush?
On Jan 9, 2014, at 7:17 PM, Weikai Xie xiewei...@gmail.com wrote: Hi, folks, I observed that it seems all ORM objects in a session will expire immediately if there is a failure in session.flush(). I was wondering what's the rationale behind this behavior. Following is an artificial web application code to illustrate the idea: def PUT(): # session and engine are all created with default parameter user = session.query(UserProfile).first() # deliberately tries to insert a Login record which has the same primary key as an existing one such that the later session.flush() will fail try: duplicated_login_record = Login(id=0, username=username:weikai) session.add(duplicated_login_record) session.flush() except IntegrityError: session.rollback() print user.id ... By turning on logging, I noticed the print user.id line always result in a new SELECT being issued to database, which is an indicator that somehow user object got expired after the failure in session.flush(). For some other good reason which I don't want to elaborate here, we really don't want to have an extra SELECT going to DB in the processing of one HTTP request. Therefore, I was just wondering why is this behavior and whether it can be turned off. The short answer is that this behavior can’t be disabled across the board, unless you are using SAVEPOINTs, which you probably should here. The flush() process does a rollback() immediately on the inner transaction when an exception occurs, and once the transaction is rolled back all data is expired; as the objects are proxies for the state of the database, and the transaction has been rolled back, the state of the objects is invalid. I do notice that you’re catching an IntegrityError.The typical pattern when writing code that wants to catch these and then continue is to run the individual set of questionable operations within a SAVEPOINT, that is a begin_nested()/commit() block. Recent versions of SQLAlchemy have the behavior such that when a flush() exception rolls back the SAVEPOINT, objects that were not modified within the SAVEPOINT are not expired; only those objects that changed within the save point’s scope do. There’s also an option called _enable_transaction_accounting which if set to False will disable *all* rollback/commit accounting, basically reverts to pre-0.5 behavior. Using this flag, you’re giving up a lot of the Session’s functionality and as this mode is not really supported I’m not sure what other useful features you might be giving up. -- You received this message because you are subscribed to the Google Groups sqlalchemy group. To unsubscribe from this group and stop receiving emails from it, send an email to sqlalchemy+unsubscr...@googlegroups.com. To post to this group, send email to sqlalchemy@googlegroups.com. Visit this group at http://groups.google.com/group/sqlalchemy. For more options, visit https://groups.google.com/groups/opt_out. signature.asc Description: Message signed with OpenPGP using GPGMail