Loading django/db/backends/postgresql_psycopg2/base.py +23 −5 Original line number Diff line number Diff line Loading @@ -93,10 +93,6 @@ class DatabaseWrapper(BaseDatabaseWrapper): def __init__(self, *args, **kwargs): super(DatabaseWrapper, self).__init__(*args, **kwargs) opts = self.settings_dict["OPTIONS"] RC = psycopg2.extensions.ISOLATION_LEVEL_READ_COMMITTED self.isolation_level = opts.get('isolation_level', RC) self.features = DatabaseFeatures(self) self.ops = DatabaseOperations(self) self.client = DatabaseClient(self) Loading Loading @@ -131,7 +127,29 @@ class DatabaseWrapper(BaseDatabaseWrapper): return conn_params def get_new_connection(self, conn_params): return Database.connect(**conn_params) connection = Database.connect(**conn_params) # self.isolation_level must be set: # - after connecting to the database in order to obtain the database's # default when no value is explicitly specified in options. # - before calling _set_autocommit() because if autocommit is on, that # will set connection.isolation_level to ISOLATION_LEVEL_AUTOCOMMIT; # and if autocommit is off, on psycopg2 < 2.4.2, _set_autocommit() # needs self.isolation_level. options = self.settings_dict['OPTIONS'] try: self.isolation_level = options['isolation_level'] except KeyError: self.isolation_level = connection.isolation_level else: # Set the isolation level to the value from OPTIONS. This isn't # needed on psycopg2 < 2.4.2 because it happens as a side-effect # of _set_autocommit(False). if (self.isolation_level != connection.isolation_level and self.psycopg2_version >= (2, 4, 2)): connection.set_session(isolation_level=self.isolation_level) return connection def init_connection_state(self): settings_dict = self.settings_dict Loading docs/releases/1.7.5.txt +4 −0 Original line number Diff line number Diff line Loading @@ -19,3 +19,7 @@ Bugfixes * Fixed crash in ``contrib.sites`` migrations when a default database isn't used (:ticket:`24332`). * Added the ability to set the isolation level on PostgreSQL with psycopg2 ≥ 2.4.2 (:ticket:`24318`). It was advertised as a new feature in Django 1.6 but it didn't work in practice. tests/backends/tests.py +28 −0 Original line number Diff line number Diff line Loading @@ -233,6 +233,34 @@ class PostgreSQLTests(TestCase): finally: new_connection.close() def test_connect_isolation_level(self): """ Regression test for #18130 and #24318. """ from psycopg2.extensions import ( ISOLATION_LEVEL_READ_COMMITTED as read_committed, ISOLATION_LEVEL_SERIALIZABLE as serializable, ) # Since this is a django.test.TestCase, a transaction is in progress # and the isolation level isn't reported as 0. This test assumes that # PostgreSQL is configured with the default isolation level. # Check the level on the psycopg2 connection, not the Django wrapper. self.assertEqual(connection.connection.isolation_level, read_committed) databases = copy.deepcopy(settings.DATABASES) databases[DEFAULT_DB_ALIAS]['OPTIONS']['isolation_level'] = serializable new_connections = ConnectionHandler(databases) new_connection = new_connections[DEFAULT_DB_ALIAS] try: # Start a transaction so the isolation level isn't reported as 0. new_connection.set_autocommit(False) # Check the level on the psycopg2 connection, not the Django wrapper. self.assertEqual(new_connection.connection.isolation_level, serializable) finally: new_connection.close() def _select(self, val): with connection.cursor() as cursor: cursor.execute("SELECT %s", (val,)) Loading Loading
django/db/backends/postgresql_psycopg2/base.py +23 −5 Original line number Diff line number Diff line Loading @@ -93,10 +93,6 @@ class DatabaseWrapper(BaseDatabaseWrapper): def __init__(self, *args, **kwargs): super(DatabaseWrapper, self).__init__(*args, **kwargs) opts = self.settings_dict["OPTIONS"] RC = psycopg2.extensions.ISOLATION_LEVEL_READ_COMMITTED self.isolation_level = opts.get('isolation_level', RC) self.features = DatabaseFeatures(self) self.ops = DatabaseOperations(self) self.client = DatabaseClient(self) Loading Loading @@ -131,7 +127,29 @@ class DatabaseWrapper(BaseDatabaseWrapper): return conn_params def get_new_connection(self, conn_params): return Database.connect(**conn_params) connection = Database.connect(**conn_params) # self.isolation_level must be set: # - after connecting to the database in order to obtain the database's # default when no value is explicitly specified in options. # - before calling _set_autocommit() because if autocommit is on, that # will set connection.isolation_level to ISOLATION_LEVEL_AUTOCOMMIT; # and if autocommit is off, on psycopg2 < 2.4.2, _set_autocommit() # needs self.isolation_level. options = self.settings_dict['OPTIONS'] try: self.isolation_level = options['isolation_level'] except KeyError: self.isolation_level = connection.isolation_level else: # Set the isolation level to the value from OPTIONS. This isn't # needed on psycopg2 < 2.4.2 because it happens as a side-effect # of _set_autocommit(False). if (self.isolation_level != connection.isolation_level and self.psycopg2_version >= (2, 4, 2)): connection.set_session(isolation_level=self.isolation_level) return connection def init_connection_state(self): settings_dict = self.settings_dict Loading
docs/releases/1.7.5.txt +4 −0 Original line number Diff line number Diff line Loading @@ -19,3 +19,7 @@ Bugfixes * Fixed crash in ``contrib.sites`` migrations when a default database isn't used (:ticket:`24332`). * Added the ability to set the isolation level on PostgreSQL with psycopg2 ≥ 2.4.2 (:ticket:`24318`). It was advertised as a new feature in Django 1.6 but it didn't work in practice.
tests/backends/tests.py +28 −0 Original line number Diff line number Diff line Loading @@ -233,6 +233,34 @@ class PostgreSQLTests(TestCase): finally: new_connection.close() def test_connect_isolation_level(self): """ Regression test for #18130 and #24318. """ from psycopg2.extensions import ( ISOLATION_LEVEL_READ_COMMITTED as read_committed, ISOLATION_LEVEL_SERIALIZABLE as serializable, ) # Since this is a django.test.TestCase, a transaction is in progress # and the isolation level isn't reported as 0. This test assumes that # PostgreSQL is configured with the default isolation level. # Check the level on the psycopg2 connection, not the Django wrapper. self.assertEqual(connection.connection.isolation_level, read_committed) databases = copy.deepcopy(settings.DATABASES) databases[DEFAULT_DB_ALIAS]['OPTIONS']['isolation_level'] = serializable new_connections = ConnectionHandler(databases) new_connection = new_connections[DEFAULT_DB_ALIAS] try: # Start a transaction so the isolation level isn't reported as 0. new_connection.set_autocommit(False) # Check the level on the psycopg2 connection, not the Django wrapper. self.assertEqual(new_connection.connection.isolation_level, serializable) finally: new_connection.close() def _select(self, val): with connection.cursor() as cursor: cursor.execute("SELECT %s", (val,)) Loading