Commit cb4a000a authored by Aymeric Augustin's avatar Aymeric Augustin
Browse files

[1.6.x] Fixed #21452 -- Non-autocommit connections to PostgreSQL.

When settings.DATABASES['default']['AUTOCOMMIT'] = False, the connection
wasn't in autocommit mode but Django pretended it was.

Thanks Anssi for analysing this issue.

Refs #17062.

Backport of 1afe7488 from master
parent b79bf9c7
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -129,10 +129,10 @@ class DatabaseWrapper(BaseDatabaseWrapper):
                conn_tz = get_parameter_status('TimeZone')

            if conn_tz != tz:
                # Set the time zone in autocommit mode (see #17062)
                self.set_autocommit(True)
                self.connection.cursor().execute(
                        self.ops.set_time_zone_sql(), [tz])
                # Commit after setting the time zone (see #17062)
                self.connection.commit()
        self.connection.set_isolation_level(self.isolation_level)

    def create_cursor(self):
+19 −4
Original line number Diff line number Diff line
@@ -352,10 +352,25 @@ class PostgresNewConnectionTests(TestCase):
            tz = cursor.fetchone()[0]
            self.assertEqual(new_tz, tz)
        finally:
            new_connection.close()

    @unittest.skipUnless(
        connection.vendor == 'postgresql',
        "This test applies only to PostgreSQL")
    def test_connect_non_autocommit(self):
        """
        The connection wrapper shouldn't believe that autocommit is enabled
        after setting the time zone when AUTOCOMMIT is False (#21452).
        """
        databases = copy.deepcopy(settings.DATABASES)
        new_connections = ConnectionHandler(databases)
        new_connection = new_connections[DEFAULT_DB_ALIAS]
        try:
            new_connection.settings_dict['AUTOCOMMIT'] = False
            cursor = new_connection.cursor()
            self.assertFalse(new_connection.get_autocommit())
        finally:
            new_connection.close()
            except DatabaseError:
                pass


# This test needs to run outside of a transaction, otherwise closing the