-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
1.1.0b3 Core PostgreSQL INSERT CTE rollback bug with engine.execute and default pool_reset_on_return #3805
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Changes by Christopher Wilson:
|
1 similar comment
Changes by Christopher Wilson:
|
Michael Bayer (@zzzeek) wrote: sure this is because the statement you're running is ultimately a SELECT, and a SELECT doesn't signal autocommit=True when a transaction is not otherwise being used. You can work around this using my_stmt = my_stmt.execution_options(autocommit=True). if you can let me know that resolves, we can work on possibly setting the flag automatically when a DML CTE is embedded into a SELECT. |
Changes by Michael Bayer (@zzzeek):
|
Changes by Michael Bayer (@zzzeek):
|
Christopher Wilson wrote: tried to clarify that the default insertQuery command will execute the COMMIT on the default engine transaction when the connection is returned to the pool, whereas the insertCTE will not. |
Changes by Christopher Wilson:
|
Changes by Christopher Wilson:
|
Changes by Christopher Wilson:
|
Changes by Christopher Wilson:
|
Christopher Wilson wrote: Ooops, I was editing that description when you responded. My bad. Thanks for the work around and the fantastic product! |
Changes by Michael Bayer (@zzzeek):
|
Changes by Michael Bayer (@zzzeek):
|
Christopher Wilson wrote: Thanks! query=query.execution_options(autocommit=True) does work. However, I do think the better option is an autocommit with a DML CTE in use. |
Christopher Wilson wrote: Interesting behavior on the workaround. Specifying a query with execution_options(autocommit=True) as a cte ignores the execution_options. For example:
At first inspection, I would expect the autocommit (if explicitly set) to be propagated to whatever query used the CTE. I realize there could be some interesting implementation edge cases if two CTEs were explicitly given different autocommit options. Of course, this could probably be mitigated by simply doing automatic inspection on the final query and setting the commit flag if the query contains a DML CTE. |
Michael Bayer (@zzzeek) wrote: IIUC we're talking here about autocommit on an inner query object propagating out to the outermost. So right now nothing does that. To fix this, we'd be looking to propagate autocommit=True to containing queries in all cases. |
Michael Bayer (@zzzeek) wrote: yeah and as far as if they conflict, shrugs, will probably just push towards True and not towards False. autocommit is not "harmful", theoretically everthing could just say COMMIT at the end rather than ROLLBACK. |
Christopher Wilson wrote: Yes. You understand correctly. It could be an implementation to get the autocommit working for DML CTE's. Inserts/Updates/Deletes automatically set the autocommit as true in UpdateBase, allowing CTE to contain/propagate that seems a straightforward approach, depending on how easy it is to lift the execution_options from subqueries, and to prefer autocommit=True over autocommit = False. Are there any other cases besides autocommit where it would be useful to propagate options up from a subquery to the parent query unless explicitly overwritten on the parent query? |
Changes by Michael Bayer (@zzzeek):
|
Migrated issue, originally created by Christopher Wilson
I'm using the new insert CTEs to implement a select or insert in one statement using the engine.execute() approach. The default reset_on_return works fine for separate select() followed by an insert() as the insert transaction is COMMITted. However, using an insert CTE, the transaction is ROLLBACKed whenever the connection is returned to the pool.
MWE: using PostgreSQL 9.3.
prints:
Setting pool_reset_on_return = 'commit':
This leads to confusing behavior:
Yes, I can arbitrarily use the pool_reset_on_return='commit' option for the engine or manually wrap it in a transaction, but the expected behavior would be a COMMIT transaction on the use of INSERT, UPDATE, or DELETE CTEs, since that is the behavior of a separate INSERT command with the default pool_reset_on_return behavior:
Gives:
The text was updated successfully, but these errors were encountered: