diff --git a/google/cloud/spanner_dbapi/connection.py b/google/cloud/spanner_dbapi/connection.py index 9befe2027d..926408c928 100644 --- a/google/cloud/spanner_dbapi/connection.py +++ b/google/cloud/spanner_dbapi/connection.py @@ -243,7 +243,10 @@ def commit(self): """ if self._autocommit: warnings.warn(AUTOCOMMIT_MODE_WARNING, UserWarning, stacklevel=2) - elif self.inside_transaction: + return + + self.run_prior_DDL_statements() + if self.inside_transaction: try: self._transaction.commit() self._release_session() diff --git a/google/cloud/spanner_dbapi/cursor.py b/google/cloud/spanner_dbapi/cursor.py index b00675dbb8..a28879faba 100644 --- a/google/cloud/spanner_dbapi/cursor.py +++ b/google/cloud/spanner_dbapi/cursor.py @@ -178,6 +178,8 @@ def execute(self, sql, args=None): ddl = ddl.strip() if ddl: self.connection._ddl_statements.append(ddl) + if self.connection.autocommit: + self.connection.run_prior_DDL_statements() return # For every other operation, we've got to ensure that diff --git a/tests/system/test_system_dbapi.py b/tests/system/test_system_dbapi.py index 1659fe239b..6ca1029ae1 100644 --- a/tests/system/test_system_dbapi.py +++ b/tests/system/test_system_dbapi.py @@ -378,6 +378,54 @@ def test_execute_many(self): self.assertEqual(res[0], 1) conn.close() + def test_DDL_autocommit(self): + """Check that DDLs in autocommit mode are immediately executed.""" + conn = Connection(Config.INSTANCE, self._db) + conn.autocommit = True + + cur = conn.cursor() + cur.execute( + """ + CREATE TABLE Singers ( + SingerId INT64 NOT NULL, + Name STRING(1024), + ) PRIMARY KEY (SingerId) + """ + ) + conn.close() + + # if previous DDL wasn't committed, the next DROP TABLE + # statement will fail with a ProgrammingError + conn = Connection(Config.INSTANCE, self._db) + cur = conn.cursor() + + cur.execute("DROP TABLE Singers") + conn.commit() + + def test_DDL_commit(self): + """Check that DDLs in commit mode are executed on calling `commit()`.""" + conn = Connection(Config.INSTANCE, self._db) + cur = conn.cursor() + + cur.execute( + """ + CREATE TABLE Singers ( + SingerId INT64 NOT NULL, + Name STRING(1024), + ) PRIMARY KEY (SingerId) + """ + ) + conn.commit() + conn.close() + + # if previous DDL wasn't committed, the next DROP TABLE + # statement will fail with a ProgrammingError + conn = Connection(Config.INSTANCE, self._db) + cur = conn.cursor() + + cur.execute("DROP TABLE Singers") + conn.commit() + def clear_table(transaction): """Clear the test table."""