Set autocommit mode before calling init_connection_state
|Reported by:||aaugustin||Owned by:||aaugustin|
|Component:||Database layer (models, ORM)||Version:||1.6|
|Has patch:||no||Needs documentation:||no|
|Needs tests:||no||Patch needs improvement:||no|
I just helped an user on IRC who attempted a fairly reasonable database backend customization:
from django.db.backends.postgresql_psycopg2 import base class DatabaseWrapper(base.DatabaseWrapper): def init_connection_state(self): super(DatabaseWrapper, self).init_connection_state() self.connection.cursor().execute('SET search_path TO something')
Unfortunately that fails with an ugly ProgrammingError: autocommit cannot be used inside a transaction and the traceback is very confusing.
The root cause of this problem is that the code above starts a transaction, and when Django later tries to switch to autocommit, PostgreSQL complains.
Would it make sense to switch to autocommit before calling init_connection_state? This is just a matter of swapping two lines in BaseDatabaseWrapper.connect, and reviewing carefully the code in init_connection_state to ensure it still works as expected. (Hint: it doesn't, see #21452.)
Currently init_connection_state executes in PEP-249 mode (= implicit transactions = no autocommit), while everything else executes in autocommit mode (unless you set AUTOCOMMIT to False in the database settings, but I'm really mentioning that for the sake of completeness, I don't expect anyone to do this). That's quite surprising and probably a good reason for making this change. Of course, there may be even better reasons for NOT making this change that I haven't thought of.
Change History (8)
comment:6 Changed 2 years ago by aaugustin
- Owner changed from nobody to aaugustin
- Status changed from new to assigned