diff options
| author | Aymeric Augustin <aymeric.augustin@m4x.org> | 2014-02-02 10:37:27 -0800 |
|---|---|---|
| committer | Aymeric Augustin <aymeric.augustin@m4x.org> | 2014-02-02 10:37:27 -0800 |
| commit | 54bfa4caab11d364eb208ba6639836fa22d69a04 (patch) | |
| tree | f24020307dd5b529989329bfabfc95effcecffe8 /tests | |
| parent | ab2f21080d8b3112c1ba9a0bf923eae733be4242 (diff) | |
| parent | 3ffeb931869cc68a8e0916219702ee282afc6e9d (diff) | |
Merge pull request #2154 from manfre/close-cursors
Fixed #21751 -- Explicitly closed cursors.
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/backends/tests.py | 53 | ||||
| -rw-r--r-- | tests/cache/tests.py | 7 | ||||
| -rw-r--r-- | tests/custom_methods/models.py | 16 | ||||
| -rw-r--r-- | tests/initial_sql_regress/tests.py | 6 | ||||
| -rw-r--r-- | tests/introspection/tests.py | 60 | ||||
| -rw-r--r-- | tests/migrations/test_base.py | 35 | ||||
| -rw-r--r-- | tests/migrations/test_operations.py | 72 | ||||
| -rw-r--r-- | tests/requests/tests.py | 2 | ||||
| -rw-r--r-- | tests/schema/tests.py | 96 | ||||
| -rw-r--r-- | tests/transactions/tests.py | 13 | ||||
| -rw-r--r-- | tests/transactions_regress/tests.py | 12 |
11 files changed, 200 insertions, 172 deletions
diff --git a/tests/backends/tests.py b/tests/backends/tests.py index 0ff3ad0bba..f3c38893f4 100644 --- a/tests/backends/tests.py +++ b/tests/backends/tests.py @@ -20,6 +20,7 @@ from django.db.backends.utils import format_number, CursorWrapper from django.db.models import Sum, Avg, Variance, StdDev from django.db.models.fields import (AutoField, DateField, DateTimeField, DecimalField, IntegerField, TimeField) +from django.db.models.sql.constants import CURSOR from django.db.utils import ConnectionHandler from django.test import (TestCase, TransactionTestCase, override_settings, skipUnlessDBFeature, skipIfDBFeature) @@ -58,9 +59,9 @@ class OracleChecks(unittest.TestCase): # stored procedure through our cursor wrapper. from django.db.backends.oracle.base import convert_unicode - cursor = connection.cursor() - cursor.callproc(convert_unicode('DBMS_SESSION.SET_IDENTIFIER'), - [convert_unicode('_django_testing!')]) + with connection.cursor() as cursor: + cursor.callproc(convert_unicode('DBMS_SESSION.SET_IDENTIFIER'), + [convert_unicode('_django_testing!')]) @unittest.skipUnless(connection.vendor == 'oracle', "No need to check Oracle cursor semantics") @@ -69,31 +70,31 @@ class OracleChecks(unittest.TestCase): # as query parameters. from django.db.backends.oracle.base import Database - cursor = connection.cursor() - var = cursor.var(Database.STRING) - cursor.execute("BEGIN %s := 'X'; END; ", [var]) - self.assertEqual(var.getvalue(), 'X') + with connection.cursor() as cursor: + var = cursor.var(Database.STRING) + cursor.execute("BEGIN %s := 'X'; END; ", [var]) + self.assertEqual(var.getvalue(), 'X') @unittest.skipUnless(connection.vendor == 'oracle', "No need to check Oracle cursor semantics") def test_long_string(self): # If the backend is Oracle, test that we can save a text longer # than 4000 chars and read it properly - c = connection.cursor() - c.execute('CREATE TABLE ltext ("TEXT" NCLOB)') - long_str = ''.join(six.text_type(x) for x in xrange(4000)) - c.execute('INSERT INTO ltext VALUES (%s)', [long_str]) - c.execute('SELECT text FROM ltext') - row = c.fetchone() - self.assertEqual(long_str, row[0].read()) - c.execute('DROP TABLE ltext') + with connection.cursor() as cursor: + cursor.execute('CREATE TABLE ltext ("TEXT" NCLOB)') + long_str = ''.join(six.text_type(x) for x in xrange(4000)) + cursor.execute('INSERT INTO ltext VALUES (%s)', [long_str]) + cursor.execute('SELECT text FROM ltext') + row = cursor.fetchone() + self.assertEqual(long_str, row[0].read()) + cursor.execute('DROP TABLE ltext') @unittest.skipUnless(connection.vendor == 'oracle', "No need to check Oracle connection semantics") def test_client_encoding(self): # If the backend is Oracle, test that the client encoding is set # correctly. This was broken under Cygwin prior to r14781. - connection.cursor() # Ensure the connection is initialized. + self.connection.ensure_connection() self.assertEqual(connection.connection.encoding, "UTF-8") self.assertEqual(connection.connection.nencoding, "UTF-8") @@ -102,12 +103,12 @@ class OracleChecks(unittest.TestCase): def test_order_of_nls_parameters(self): # an 'almost right' datetime should work with configured # NLS parameters as per #18465. - c = connection.cursor() - query = "select 1 from dual where '1936-12-29 00:00' < sysdate" - # Test that the query succeeds without errors - pre #18465 this - # wasn't the case. - c.execute(query) - self.assertEqual(c.fetchone()[0], 1) + with connection.cursor() as cursor: + query = "select 1 from dual where '1936-12-29 00:00' < sysdate" + # Test that the query succeeds without errors - pre #18465 this + # wasn't the case. + cursor.execute(query) + self.assertEqual(cursor.fetchone()[0], 1) class SQLiteTests(TestCase): @@ -209,7 +210,7 @@ class LastExecutedQueryTest(TestCase): """ persons = models.Reporter.objects.filter(raw_data=b'\x00\x46 \xFE').extra(select={'föö': 1}) sql, params = persons.query.sql_with_params() - cursor = persons.query.get_compiler('default').execute_sql(None) + cursor = persons.query.get_compiler('default').execute_sql(CURSOR) last_sql = cursor.db.ops.last_executed_query(cursor, sql, params) self.assertIsInstance(last_sql, six.text_type) @@ -327,6 +328,12 @@ class PostgresVersionTest(TestCase): def fetchone(self): return ["PostgreSQL 8.3"] + def __enter__(self): + return self + + def __exit__(self, type, value, traceback): + pass + class OlderConnectionMock(object): "Mock of psycopg2 (< 2.0.12) connection" def cursor(self): diff --git a/tests/cache/tests.py b/tests/cache/tests.py index 94790ed740..bc0f705375 100644 --- a/tests/cache/tests.py +++ b/tests/cache/tests.py @@ -896,10 +896,9 @@ class DBCacheTests(BaseCacheTests, TransactionTestCase): management.call_command('createcachetable', verbosity=0, interactive=False) def drop_table(self): - cursor = connection.cursor() - table_name = connection.ops.quote_name('test cache table') - cursor.execute('DROP TABLE %s' % table_name) - cursor.close() + with connection.cursor() as cursor: + table_name = connection.ops.quote_name('test cache table') + cursor.execute('DROP TABLE %s' % table_name) def test_zero_cull(self): self._perform_cull_test(caches['zero_cull'], 50, 18) diff --git a/tests/custom_methods/models.py b/tests/custom_methods/models.py index cef3fd722b..78e00a99b8 100644 --- a/tests/custom_methods/models.py +++ b/tests/custom_methods/models.py @@ -30,11 +30,11 @@ class Article(models.Model): database query for the sake of demonstration. """ from django.db import connection - cursor = connection.cursor() - cursor.execute(""" - SELECT id, headline, pub_date - FROM custom_methods_article - WHERE pub_date = %s - AND id != %s""", [connection.ops.value_to_db_date(self.pub_date), - self.id]) - return [self.__class__(*row) for row in cursor.fetchall()] + with connection.cursor() as cursor: + cursor.execute(""" + SELECT id, headline, pub_date + FROM custom_methods_article + WHERE pub_date = %s + AND id != %s""", [connection.ops.value_to_db_date(self.pub_date), + self.id]) + return [self.__class__(*row) for row in cursor.fetchall()] diff --git a/tests/initial_sql_regress/tests.py b/tests/initial_sql_regress/tests.py index e725f4b102..428d993667 100644 --- a/tests/initial_sql_regress/tests.py +++ b/tests/initial_sql_regress/tests.py @@ -28,9 +28,9 @@ class InitialSQLTests(TestCase): connection = connections[DEFAULT_DB_ALIAS] custom_sql = custom_sql_for_model(Simple, no_style(), connection) self.assertEqual(len(custom_sql), 9) - cursor = connection.cursor() - for sql in custom_sql: - cursor.execute(sql) + with connection.cursor() as cursor: + for sql in custom_sql: + cursor.execute(sql) self.assertEqual(Simple.objects.count(), 9) self.assertEqual( Simple.objects.get(name__contains='placeholders').name, diff --git a/tests/introspection/tests.py b/tests/introspection/tests.py index 8ec3d39903..0c339bc8ea 100644 --- a/tests/introspection/tests.py +++ b/tests/introspection/tests.py @@ -23,17 +23,17 @@ class IntrospectionTests(TestCase): "'%s' isn't in table_list()." % Article._meta.db_table) def test_django_table_names(self): - cursor = connection.cursor() - cursor.execute('CREATE TABLE django_ixn_test_table (id INTEGER);') - tl = connection.introspection.django_table_names() - cursor.execute("DROP TABLE django_ixn_test_table;") - self.assertTrue('django_ixn_testcase_table' not in tl, - "django_table_names() returned a non-Django table") + with connection.cursor() as cursor: + cursor.execute('CREATE TABLE django_ixn_test_table (id INTEGER);') + tl = connection.introspection.django_table_names() + cursor.execute("DROP TABLE django_ixn_test_table;") + self.assertTrue('django_ixn_testcase_table' not in tl, + "django_table_names() returned a non-Django table") def test_django_table_names_retval_type(self): # Ticket #15216 - cursor = connection.cursor() - cursor.execute('CREATE TABLE django_ixn_test_table (id INTEGER);') + with connection.cursor() as cursor: + cursor.execute('CREATE TABLE django_ixn_test_table (id INTEGER);') tl = connection.introspection.django_table_names(only_existing=True) self.assertIs(type(tl), list) @@ -53,14 +53,14 @@ class IntrospectionTests(TestCase): 'Reporter sequence not found in sequence_list()') def test_get_table_description_names(self): - cursor = connection.cursor() - desc = connection.introspection.get_table_description(cursor, Reporter._meta.db_table) + with connection.cursor() as cursor: + desc = connection.introspection.get_table_description(cursor, Reporter._meta.db_table) self.assertEqual([r[0] for r in desc], [f.column for f in Reporter._meta.fields]) def test_get_table_description_types(self): - cursor = connection.cursor() - desc = connection.introspection.get_table_description(cursor, Reporter._meta.db_table) + with connection.cursor() as cursor: + desc = connection.introspection.get_table_description(cursor, Reporter._meta.db_table) # The MySQL exception is due to the cursor.description returning the same constant for # text and blob columns. TODO: use information_schema database to retrieve the proper # field type on MySQL @@ -75,8 +75,8 @@ class IntrospectionTests(TestCase): # inspect the length of character columns). @expectedFailureOnOracle def test_get_table_description_col_lengths(self): - cursor = connection.cursor() - desc = connection.introspection.get_table_description(cursor, Reporter._meta.db_table) + with connection.cursor() as cursor: + desc = connection.introspection.get_table_description(cursor, Reporter._meta.db_table) self.assertEqual( [r[3] for r in desc if datatype(r[1], r) == 'CharField'], [30, 30, 75] @@ -87,8 +87,8 @@ class IntrospectionTests(TestCase): # so its idea about null_ok in cursor.description is different from ours. @skipIfDBFeature('interprets_empty_strings_as_nulls') def test_get_table_description_nullable(self): - cursor = connection.cursor() - desc = connection.introspection.get_table_description(cursor, Reporter._meta.db_table) + with connection.cursor() as cursor: + desc = connection.introspection.get_table_description(cursor, Reporter._meta.db_table) self.assertEqual( [r[6] for r in desc], [False, False, False, False, True, True] @@ -97,15 +97,15 @@ class IntrospectionTests(TestCase): # Regression test for #9991 - 'real' types in postgres @skipUnlessDBFeature('has_real_datatype') def test_postgresql_real_type(self): - cursor = connection.cursor() - cursor.execute("CREATE TABLE django_ixn_real_test_table (number REAL);") - desc = connection.introspection.get_table_description(cursor, 'django_ixn_real_test_table') - cursor.execute('DROP TABLE django_ixn_real_test_table;') + with connection.cursor() as cursor: + cursor.execute("CREATE TABLE django_ixn_real_test_table (number REAL);") + desc = connection.introspection.get_table_description(cursor, 'django_ixn_real_test_table') + cursor.execute('DROP TABLE django_ixn_real_test_table;') self.assertEqual(datatype(desc[0][1], desc[0]), 'FloatField') def test_get_relations(self): - cursor = connection.cursor() - relations = connection.introspection.get_relations(cursor, Article._meta.db_table) + with connection.cursor() as cursor: + relations = connection.introspection.get_relations(cursor, Article._meta.db_table) # Older versions of MySQL don't have the chops to report on this stuff, # so just skip it if no relations come back. If they do, though, we @@ -117,21 +117,21 @@ class IntrospectionTests(TestCase): @skipUnlessDBFeature('can_introspect_foreign_keys') def test_get_key_columns(self): - cursor = connection.cursor() - key_columns = connection.introspection.get_key_columns(cursor, Article._meta.db_table) + with connection.cursor() as cursor: + key_columns = connection.introspection.get_key_columns(cursor, Article._meta.db_table) self.assertEqual( set(key_columns), set([('reporter_id', Reporter._meta.db_table, 'id'), ('response_to_id', Article._meta.db_table, 'id')])) def test_get_primary_key_column(self): - cursor = connection.cursor() - primary_key_column = connection.introspection.get_primary_key_column(cursor, Article._meta.db_table) + with connection.cursor() as cursor: + primary_key_column = connection.introspection.get_primary_key_column(cursor, Article._meta.db_table) self.assertEqual(primary_key_column, 'id') def test_get_indexes(self): - cursor = connection.cursor() - indexes = connection.introspection.get_indexes(cursor, Article._meta.db_table) + with connection.cursor() as cursor: + indexes = connection.introspection.get_indexes(cursor, Article._meta.db_table) self.assertEqual(indexes['reporter_id'], {'unique': False, 'primary_key': False}) def test_get_indexes_multicol(self): @@ -139,8 +139,8 @@ class IntrospectionTests(TestCase): Test that multicolumn indexes are not included in the introspection results. """ - cursor = connection.cursor() - indexes = connection.introspection.get_indexes(cursor, Reporter._meta.db_table) + with connection.cursor() as cursor: + indexes = connection.introspection.get_indexes(cursor, Reporter._meta.db_table) self.assertNotIn('first_name', indexes) self.assertIn('id', indexes) diff --git a/tests/migrations/test_base.py b/tests/migrations/test_base.py index 7ab09b04a5..2dba30b2aa 100644 --- a/tests/migrations/test_base.py +++ b/tests/migrations/test_base.py @@ -9,33 +9,40 @@ class MigrationTestBase(TransactionTestCase): available_apps = ["migrations"] + def get_table_description(self, table): + with connection.cursor() as cursor: + return connection.introspection.get_table_description(cursor, table) + def assertTableExists(self, table): - self.assertIn(table, connection.introspection.get_table_list(connection.cursor())) + with connection.cursor() as cursor: + self.assertIn(table, connection.introspection.get_table_list(cursor)) def assertTableNotExists(self, table): - self.assertNotIn(table, connection.introspection.get_table_list(connection.cursor())) + with connection.cursor() as cursor: + self.assertNotIn(table, connection.introspection.get_table_list(cursor)) def assertColumnExists(self, table, column): - self.assertIn(column, [c.name for c in connection.introspection.get_table_description(connection.cursor(), table)]) + self.assertIn(column, [c.name for c in self.get_table_description(table)]) def assertColumnNotExists(self, table, column): - self.assertNotIn(column, [c.name for c in connection.introspection.get_table_description(connection.cursor(), table)]) + self.assertNotIn(column, [c.name for c in self.get_table_description(table)]) def assertColumnNull(self, table, column): - self.assertEqual([c.null_ok for c in connection.introspection.get_table_description(connection.cursor(), table) if c.name == column][0], True) + self.assertEqual([c.null_ok for c in self.get_table_description(table) if c.name == column][0], True) def assertColumnNotNull(self, table, column): - self.assertEqual([c.null_ok for c in connection.introspection.get_table_description(connection.cursor(), table) if c.name == column][0], False) + self.assertEqual([c.null_ok for c in self.get_table_description(table) if c.name == column][0], False) def assertIndexExists(self, table, columns, value=True): - self.assertEqual( - value, - any( - c["index"] - for c in connection.introspection.get_constraints(connection.cursor(), table).values() - if c['columns'] == list(columns) - ), - ) + with connection.cursor() as cursor: + self.assertEqual( + value, + any( + c["index"] + for c in connection.introspection.get_constraints(cursor, table).values() + if c['columns'] == list(columns) + ), + ) def assertIndexNotExists(self, table, columns): return self.assertIndexExists(table, columns, False) diff --git a/tests/migrations/test_operations.py b/tests/migrations/test_operations.py index eda356fd5d..375a9ccc54 100644 --- a/tests/migrations/test_operations.py +++ b/tests/migrations/test_operations.py @@ -19,15 +19,15 @@ class OperationTests(MigrationTestBase): Creates a test model state and database table. """ # Delete the tables if they already exist - cursor = connection.cursor() - try: - cursor.execute("DROP TABLE %s_pony" % app_label) - except: - pass - try: - cursor.execute("DROP TABLE %s_stable" % app_label) - except: - pass + with connection.cursor() as cursor: + try: + cursor.execute("DROP TABLE %s_pony" % app_label) + except: + pass + try: + cursor.execute("DROP TABLE %s_stable" % app_label) + except: + pass # Make the "current" state operations = [migrations.CreateModel( "Pony", @@ -348,21 +348,21 @@ class OperationTests(MigrationTestBase): operation.state_forwards("test_alflpkfk", new_state) self.assertIsInstance(project_state.models["test_alflpkfk", "pony"].get_field_by_name("id"), models.AutoField) self.assertIsInstance(new_state.models["test_alflpkfk", "pony"].get_field_by_name("id"), models.FloatField) + + def assertIdTypeEqualsFkType(self): + with connection.cursor() as cursor: + id_type = [c.type_code for c in connection.introspection.get_table_description(cursor, "test_alflpkfk_pony") if c.name == "id"][0] + fk_type = [c.type_code for c in connection.introspection.get_table_description(cursor, "test_alflpkfk_rider") if c.name == "pony_id"][0] + self.assertEqual(id_type, fk_type) + assertIdTypeEqualsFkType() # Test the database alteration - id_type = [c.type_code for c in connection.introspection.get_table_description(connection.cursor(), "test_alflpkfk_pony") if c.name == "id"][0] - fk_type = [c.type_code for c in connection.introspection.get_table_description(connection.cursor(), "test_alflpkfk_rider") if c.name == "pony_id"][0] - self.assertEqual(id_type, fk_type) with connection.schema_editor() as editor: operation.database_forwards("test_alflpkfk", editor, project_state, new_state) - id_type = [c.type_code for c in connection.introspection.get_table_description(connection.cursor(), "test_alflpkfk_pony") if c.name == "id"][0] - fk_type = [c.type_code for c in connection.introspection.get_table_description(connection.cursor(), "test_alflpkfk_rider") if c.name == "pony_id"][0] - self.assertEqual(id_type, fk_type) + assertIdTypeEqualsFkType() # And test reversal with connection.schema_editor() as editor: operation.database_backwards("test_alflpkfk", editor, new_state, project_state) - id_type = [c.type_code for c in connection.introspection.get_table_description(connection.cursor(), "test_alflpkfk_pony") if c.name == "id"][0] - fk_type = [c.type_code for c in connection.introspection.get_table_description(connection.cursor(), "test_alflpkfk_rider") if c.name == "pony_id"][0] - self.assertEqual(id_type, fk_type) + assertIdTypeEqualsFkType() def test_rename_field(self): """ @@ -400,24 +400,24 @@ class OperationTests(MigrationTestBase): self.assertEqual(len(project_state.models["test_alunto", "pony"].options.get("unique_together", set())), 0) self.assertEqual(len(new_state.models["test_alunto", "pony"].options.get("unique_together", set())), 1) # Make sure we can insert duplicate rows - cursor = connection.cursor() - cursor.execute("INSERT INTO test_alunto_pony (id, pink, weight) VALUES (1, 1, 1)") - cursor.execute("INSERT INTO test_alunto_pony (id, pink, weight) VALUES (2, 1, 1)") - cursor.execute("DELETE FROM test_alunto_pony") - # Test the database alteration - with connection.schema_editor() as editor: - operation.database_forwards("test_alunto", editor, project_state, new_state) - cursor.execute("INSERT INTO test_alunto_pony (id, pink, weight) VALUES (1, 1, 1)") - with self.assertRaises(IntegrityError): - with atomic(): - cursor.execute("INSERT INTO test_alunto_pony (id, pink, weight) VALUES (2, 1, 1)") - cursor.execute("DELETE FROM test_alunto_pony") - # And test reversal - with connection.schema_editor() as editor: - operation.database_backwards("test_alunto", editor, new_state, project_state) - cursor.execute("INSERT INTO test_alunto_pony (id, pink, weight) VALUES (1, 1, 1)") - cursor.execute("INSERT INTO test_alunto_pony (id, pink, weight) VALUES (2, 1, 1)") - cursor.execute("DELETE FROM test_alunto_pony") + with connection.cursor() as cursor: + cursor.execute("INSERT INTO test_alunto_pony (id, pink, weight) VALUES (1, 1, 1)") + cursor.execute("INSERT INTO test_alunto_pony (id, pink, weight) VALUES (2, 1, 1)") + cursor.execute("DELETE FROM test_alunto_pony") + # Test the database alteration + with connection.schema_editor() as editor: + operation.database_forwards("test_alunto", editor, project_state, new_state) + cursor.execute("INSERT INTO test_alunto_pony (id, pink, weight) VALUES (1, 1, 1)") + with self.assertRaises(IntegrityError): + with atomic(): + cursor.execute("INSERT INTO test_alunto_pony (id, pink, weight) VALUES (2, 1, 1)") + cursor.execute("DELETE FROM test_alunto_pony") + # And test reversal + with connection.schema_editor() as editor: + operation.database_backwards("test_alunto", editor, new_state, project_state) + cursor.execute("INSERT INTO test_alunto_pony (id, pink, weight) VALUES (1, 1, 1)") + cursor.execute("INSERT INTO test_alunto_pony (id, pink, weight) VALUES (2, 1, 1)") + cursor.execute("DELETE FROM test_alunto_pony") # Test flat unique_together operation = migrations.AlterUniqueTogether("Pony", ("pink", "weight")) operation.state_forwards("test_alunto", new_state) diff --git a/tests/requests/tests.py b/tests/requests/tests.py index bb56369371..3e594376aa 100644 --- a/tests/requests/tests.py +++ b/tests/requests/tests.py @@ -725,7 +725,7 @@ class DatabaseConnectionHandlingTests(TransactionTestCase): # request_finished signal. response = self.client.get('/') # Make sure there is an open connection - connection.cursor() + self.connection.ensure_connection() connection.enter_transaction_management() signals.request_finished.send(sender=response._handler_class) self.assertEqual(len(connection.transaction_state), 0) diff --git a/tests/schema/tests.py b/tests/schema/tests.py index 450362ecda..a502ef6002 100644 --- a/tests/schema/tests.py +++ b/tests/schema/tests.py @@ -37,38 +37,38 @@ class SchemaTests(TransactionTestCase): def delete_tables(self): "Deletes all model tables for our models for a clean test environment" - cursor = connection.cursor() - connection.disable_constraint_checking() - table_names = connection.introspection.table_names(cursor) - for model in self.models: - # Remove any M2M tables first - for field in model._meta.local_many_to_many: + with connection.cursor() as cursor: + connection.disable_constraint_checking() + table_names = connection.introspection.table_names(cursor) + for model in self.models: + # Remove any M2M tables first + for field in model._meta.local_many_to_many: + with atomic(): + tbl = field.rel.through._meta.db_table + if tbl in table_names: + cursor.execute(connection.schema_editor().sql_delete_table % { + "table": connection.ops.quote_name(tbl), + }) + table_names.remove(tbl) + # Then remove the main tables with atomic(): - tbl = field.rel.through._meta.db_table + tbl = model._meta.db_table if tbl in table_names: cursor.execute(connection.schema_editor().sql_delete_table % { "table": connection.ops.quote_name(tbl), }) table_names.remove(tbl) - # Then remove the main tables - with atomic(): - tbl = model._meta.db_table - if tbl in table_names: - cursor.execute(connection.schema_editor().sql_delete_table % { - "table": connection.ops.quote_name(tbl), - }) - table_names.remove(tbl) connection.enable_constraint_checking() def column_classes(self, model): - cursor = connection.cursor() - columns = dict( - (d[0], (connection.introspection.get_field_type(d[1], d), d)) - for d in connection.introspection.get_table_description( - cursor, - model._meta.db_table, + with connection.cursor() as cursor: + columns = dict( + (d[0], (connection.introspection.get_field_type(d[1], d), d)) + for d in connection.introspection.get_table_description( + cursor, + model._meta.db_table, + ) ) - ) # SQLite has a different format for field_type for name, (type, desc) in columns.items(): if isinstance(type, tuple): @@ -78,6 +78,20 @@ class SchemaTests(TransactionTestCase): raise DatabaseError("Table does not exist (empty pragma)") return columns + def get_indexes(self, table): + """ + Get the indexes on the table using a new cursor. + """ + with connection.cursor() as cursor: + return connection.introspection.get_indexes(cursor, table) + + def get_constraints(self, table): + """ + Get the constraints on a table using a new cursor. + """ + with connection.cursor() as cursor: + return connection.introspection.get_constraints(cursor, table) + # Tests def test_creation_deletion(self): @@ -127,7 +141,7 @@ class SchemaTests(TransactionTestCase): strict=True, ) # Make sure the new FK constraint is present - constraints = connection.introspection.get_constraints(connection.cursor(), Book._meta.db_table) + constraints = self.get_constraints(Book._meta.db_table) for name, details in constraints.items(): if details['columns'] == ["author_id"] and details['foreign_key']: self.assertEqual(details['foreign_key'], ('schema_tag', 'id')) @@ -342,7 +356,7 @@ class SchemaTests(TransactionTestCase): editor.create_model(TagM2MTest) editor.create_model(UniqueTest) # Ensure the M2M exists and points to TagM2MTest - constraints = connection.introspection.get_constraints(connection.cursor(), BookWithM2M._meta.get_field_by_name("tags")[0].rel.through._meta.db_table) + constraints = self.get_constraints(BookWithM2M._meta.get_field_by_name("tags")[0].rel.through._meta.db_table) if connection.features.supports_foreign_keys: for name, details in constraints.items(): if details['columns'] == ["tagm2mtest_id"] and details['foreign_key']: @@ -363,7 +377,7 @@ class SchemaTests(TransactionTestCase): # Ensure old M2M is gone self.assertRaises(DatabaseError, self.column_classes, BookWithM2M._meta.get_field_by_name("tags")[0].rel.through) # Ensure the new M2M exists and points to UniqueTest - constraints = connection.introspection.get_constraints(connection.cursor(), new_field.rel.through._meta.db_table) + constraints = self.get_constraints(new_field.rel.through._meta.db_table) if connection.features.supports_foreign_keys: for name, details in constraints.items(): if details['columns'] == ["uniquetest_id"] and details['foreign_key']: @@ -388,7 +402,7 @@ class SchemaTests(TransactionTestCase): with connection.schema_editor() as editor: editor.create_model(Author) # Ensure the constraint exists - constraints = connection.introspection.get_constraints(connection.cursor(), Author._meta.db_table) + constraints = self.get_constraints(Author._meta.db_table) for name, details in constraints.items(): if details['columns'] == ["height"] and details['check']: break @@ -404,7 +418,7 @@ class SchemaTests(TransactionTestCase): new_field, strict=True, ) - constraints = connection.introspection.get_constraints(connection.cursor(), Author._meta.db_table) + constraints = self.get_constraints(Author._meta.db_table) for name, details in constraints.items(): if details['columns'] == ["height"] and details['check']: self.fail("Check constraint for height found") @@ -416,7 +430,7 @@ class SchemaTests(TransactionTestCase): Author._meta.get_field_by_name("height")[0], strict=True, ) - constraints = connection.introspection.get_constraints(connection.cursor(), Author._meta.db_table) + constraints = self.get_constraints(Author._meta.db_table) for name, details in constraints.items(): if details['columns'] == ["height"] and details['check']: break @@ -527,7 +541,7 @@ class SchemaTests(TransactionTestCase): False, any( c["index"] - for c in connection.introspection.get_constraints(connection.cursor(), "schema_tag").values() + for c in self.get_constraints("schema_tag").values() if c['columns'] == ["slug", "title"] ), ) @@ -543,7 +557,7 @@ class SchemaTests(TransactionTestCase): True, any( c["index"] - for c in connection.introspection.get_constraints(connection.cursor(), "schema_tag").values() + for c in self.get_constraints("schema_tag").values() if c['columns'] == ["slug", "title"] ), ) @@ -561,7 +575,7 @@ class SchemaTests(TransactionTestCase): False, any( c["index"] - for c in connection.introspection.get_constraints(connection.cursor(), "schema_tag").values() + for c in self.get_constraints("schema_tag").values() if c['columns'] == ["slug", "title"] ), ) @@ -578,7 +592,7 @@ class SchemaTests(TransactionTestCase): True, any( c["index"] - for c in connection.introspection.get_constraints(connection.cursor(), "schema_tagindexed").values() + for c in self.get_constraints("schema_tagindexed").values() if c['columns'] == ["slug", "title"] ), ) @@ -627,7 +641,7 @@ class SchemaTests(TransactionTestCase): # Ensure the table is there and has the right index self.assertIn( "title", - connection.introspection.get_indexes(connection.cursor(), Book._meta.db_table), + self.get_indexes(Book._meta.db_table), ) # Alter to remove the index new_field = CharField(max_length=100, db_index=False) @@ -642,7 +656,7 @@ class SchemaTests(TransactionTestCase): # Ensure the table is there and has no index self.assertNotIn( "title", - connection.introspection.get_indexes(connection.cursor(), Book._meta.db_table), + self.get_indexes(Book._meta.db_table), ) # Alter to re-add the index with connection.schema_editor() as editor: @@ -655,7 +669,7 @@ class SchemaTests(TransactionTestCase): # Ensure the table is there and has the index again self.assertIn( "title", - connection.introspection.get_indexes(connection.cursor(), Book._meta.db_table), + self.get_indexes(Book._meta.db_table), ) # Add a unique column, verify that creates an implicit index with connection.schema_editor() as editor: @@ -665,7 +679,7 @@ class SchemaTests(TransactionTestCase): ) self.assertIn( "slug", - connection.introspection.get_indexes(connection.cursor(), Book._meta.db_table), + self.get_indexes(Book._meta.db_table), ) # Remove the unique, check the index goes with it new_field2 = CharField(max_length=20, unique=False) @@ -679,7 +693,7 @@ class SchemaTests(TransactionTestCase): ) self.assertNotIn( "slug", - connection.introspection.get_indexes(connection.cursor(), Book._meta.db_table), + self.get_indexes(Book._meta.db_table), ) def test_primary_key(self): @@ -691,7 +705,7 @@ class SchemaTests(TransactionTestCase): editor.create_model(Tag) # Ensure the table is there and has the right PK self.assertTrue( - connection.introspection.get_indexes(connection.cursor(), Tag._meta.db_table)['id']['primary_key'], + self.get_indexes(Tag._meta.db_table)['id']['primary_key'], ) # Alter to change the PK new_field = SlugField(primary_key=True) @@ -707,10 +721,10 @@ class SchemaTests(TransactionTestCase): # Ensure the PK changed self.assertNotIn( 'id', - connection.introspection.get_indexes(connection.cursor(), Tag._meta.db_table), + self.get_indexes(Tag._meta.db_table), ) self.assertTrue( - connection.introspection.get_indexes(connection.cursor(), Tag._meta.db_table)['slug']['primary_key'], + self.get_indexes(Tag._meta.db_table)['slug']['primary_key'], ) def test_context_manager_exit(self): @@ -741,7 +755,7 @@ class SchemaTests(TransactionTestCase): # Ensure the table is there and has an index on the column self.assertIn( column_name, - connection.introspection.get_indexes(connection.cursor(), BookWithLongName._meta.db_table), + self.get_indexes(BookWithLongName._meta.db_table), ) def test_creation_deletion_reserved_names(self): diff --git a/tests/transactions/tests.py b/tests/transactions/tests.py index 5c38bc8ef2..e7ce43cd93 100644 --- a/tests/transactions/tests.py +++ b/tests/transactions/tests.py @@ -202,8 +202,9 @@ class AtomicTests(TransactionTestCase): # trigger a database error inside an inner atomic without savepoint with self.assertRaises(DatabaseError): with transaction.atomic(savepoint=False): - connection.cursor().execute( - "SELECT no_such_col FROM transactions_reporter") + with connection.cursor() as cursor: + cursor.execute( + "SELECT no_such_col FROM transactions_reporter") # prevent atomic from rolling back since we're recovering manually self.assertTrue(transaction.get_rollback()) transaction.set_rollback(False) @@ -534,8 +535,8 @@ class TransactionRollbackTests(IgnoreDeprecationWarningsMixin, TransactionTestCa available_apps = ['transactions'] def execute_bad_sql(self): - cursor = connection.cursor() - cursor.execute("INSERT INTO transactions_reporter (first_name, last_name) VALUES ('Douglas', 'Adams');") + with connection.cursor() as cursor: + cursor.execute("INSERT INTO transactions_reporter (first_name, last_name) VALUES ('Douglas', 'Adams');") @skipUnlessDBFeature('requires_rollback_on_dirty_transaction') def test_bad_sql(self): @@ -678,6 +679,6 @@ class TransactionContextManagerTests(IgnoreDeprecationWarningsMixin, Transaction """ with self.assertRaises(IntegrityError): with transaction.commit_on_success(): - cursor = connection.cursor() - cursor.execute("INSERT INTO transactions_reporter (first_name, last_name) VALUES ('Douglas', 'Adams');") + with connection.cursor() as cursor: + cursor.execute("INSERT INTO transactions_reporter (first_name, last_name) VALUES ('Douglas', 'Adams');") transaction.rollback() diff --git a/tests/transactions_regress/tests.py b/tests/transactions_regress/tests.py index cada46edb2..1f9f291307 100644 --- a/tests/transactions_regress/tests.py +++ b/tests/transactions_regress/tests.py @@ -54,8 +54,8 @@ class TestTransactionClosing(IgnoreDeprecationWarningsMixin, TransactionTestCase @commit_on_success def raw_sql(): "Write a record using raw sql under a commit_on_success decorator" - cursor = connection.cursor() - cursor.execute("INSERT into transactions_regress_mod (fld) values (18)") + with connection.cursor() as cursor: + cursor.execute("INSERT into transactions_regress_mod (fld) values (18)") raw_sql() # Rollback so that if the decorator didn't commit, the record is unwritten @@ -143,10 +143,10 @@ class TestTransactionClosing(IgnoreDeprecationWarningsMixin, TransactionTestCase (reference). All this under commit_on_success, so the second insert should be committed. """ - cursor = connection.cursor() - cursor.execute("INSERT into transactions_regress_mod (fld) values (2)") - transaction.rollback() - cursor.execute("INSERT into transactions_regress_mod (fld) values (2)") + with connection.cursor() as cursor: + cursor.execute("INSERT into transactions_regress_mod (fld) values (2)") + transaction.rollback() + cursor.execute("INSERT into transactions_regress_mod (fld) values (2)") reuse_cursor_ref() # Rollback so that if the decorator didn't commit, the record is unwritten |
