summaryrefslogtreecommitdiff
path: root/django
diff options
context:
space:
mode:
authorJon Dufresne <jon.dufresne@gmail.com>2017-11-28 05:12:28 -0800
committerTim Graham <timograham@gmail.com>2017-11-28 11:28:09 -0500
commit7a6fbf36b1fdb8978ea0842075ccce83bcd63789 (patch)
treea48e72be7e31066d92de43a85458b0bfb7e2cfcd /django
parent3308085838f520db49f606b72345a301c1cf2a3e (diff)
Fixed #28853 -- Updated connection.cursor() uses to use a context manager.
Diffstat (limited to 'django')
-rw-r--r--django/contrib/gis/db/backends/mysql/introspection.py6
-rw-r--r--django/contrib/gis/db/backends/oracle/introspection.py6
-rw-r--r--django/contrib/gis/db/backends/postgis/introspection.py12
-rw-r--r--django/contrib/gis/db/backends/spatialite/introspection.py6
-rw-r--r--django/db/backends/base/base.py5
-rw-r--r--django/db/backends/base/introspection.py29
-rw-r--r--django/db/backends/mysql/base.py57
-rw-r--r--django/db/backends/oracle/creation.py147
-rw-r--r--django/db/backends/sqlite3/base.py58
-rw-r--r--django/db/migrations/executor.py3
-rw-r--r--django/test/testcases.py6
11 files changed, 155 insertions, 180 deletions
diff --git a/django/contrib/gis/db/backends/mysql/introspection.py b/django/contrib/gis/db/backends/mysql/introspection.py
index 364cdeecfe..ba125ec4af 100644
--- a/django/contrib/gis/db/backends/mysql/introspection.py
+++ b/django/contrib/gis/db/backends/mysql/introspection.py
@@ -11,8 +11,7 @@ class MySQLIntrospection(DatabaseIntrospection):
data_types_reverse[FIELD_TYPE.GEOMETRY] = 'GeometryField'
def get_geometry_type(self, table_name, geo_col):
- cursor = self.connection.cursor()
- try:
+ with self.connection.cursor() as cursor:
# In order to get the specific geometry type of the field,
# we introspect on the table definition using `DESCRIBE`.
cursor.execute('DESCRIBE %s' %
@@ -27,9 +26,6 @@ class MySQLIntrospection(DatabaseIntrospection):
field_type = OGRGeomType(typ).django
field_params = {}
break
- finally:
- cursor.close()
-
return field_type, field_params
def supports_spatial_index(self, cursor, table_name):
diff --git a/django/contrib/gis/db/backends/oracle/introspection.py b/django/contrib/gis/db/backends/oracle/introspection.py
index 446dc78216..7f4f886a34 100644
--- a/django/contrib/gis/db/backends/oracle/introspection.py
+++ b/django/contrib/gis/db/backends/oracle/introspection.py
@@ -11,8 +11,7 @@ class OracleIntrospection(DatabaseIntrospection):
data_types_reverse[cx_Oracle.OBJECT] = 'GeometryField'
def get_geometry_type(self, table_name, geo_col):
- cursor = self.connection.cursor()
- try:
+ with self.connection.cursor() as cursor:
# Querying USER_SDO_GEOM_METADATA to get the SRID and dimension information.
try:
cursor.execute(
@@ -40,7 +39,4 @@ class OracleIntrospection(DatabaseIntrospection):
dim = dim.size()
if dim != 2:
field_params['dim'] = dim
- finally:
- cursor.close()
-
return field_type, field_params
diff --git a/django/contrib/gis/db/backends/postgis/introspection.py b/django/contrib/gis/db/backends/postgis/introspection.py
index 3a90ebf5c5..97fa7480e6 100644
--- a/django/contrib/gis/db/backends/postgis/introspection.py
+++ b/django/contrib/gis/db/backends/postgis/introspection.py
@@ -59,15 +59,11 @@ class PostGISIntrospection(DatabaseIntrospection):
# to query the PostgreSQL pg_type table corresponding to the
# PostGIS custom data types.
oid_sql = 'SELECT "oid" FROM "pg_type" WHERE "typname" = %s'
- cursor = self.connection.cursor()
- try:
+ with self.connection.cursor() as cursor:
for field_type in field_types:
cursor.execute(oid_sql, (field_type[0],))
for result in cursor.fetchall():
postgis_types[result[0]] = field_type[1]
- finally:
- cursor.close()
-
return postgis_types
def get_field_type(self, data_type, description):
@@ -88,8 +84,7 @@ class PostGISIntrospection(DatabaseIntrospection):
PointField or a PolygonField). Thus, this routine queries the PostGIS
metadata tables to determine the geometry type.
"""
- cursor = self.connection.cursor()
- try:
+ with self.connection.cursor() as cursor:
try:
# First seeing if this geometry column is in the `geometry_columns`
cursor.execute('SELECT "coord_dimension", "srid", "type" '
@@ -122,7 +117,4 @@ class PostGISIntrospection(DatabaseIntrospection):
field_params['srid'] = srid
if dim != 2:
field_params['dim'] = dim
- finally:
- cursor.close()
-
return field_type, field_params
diff --git a/django/contrib/gis/db/backends/spatialite/introspection.py b/django/contrib/gis/db/backends/spatialite/introspection.py
index 98fda427d0..5cd5613b69 100644
--- a/django/contrib/gis/db/backends/spatialite/introspection.py
+++ b/django/contrib/gis/db/backends/spatialite/introspection.py
@@ -25,8 +25,7 @@ class SpatiaLiteIntrospection(DatabaseIntrospection):
data_types_reverse = GeoFlexibleFieldLookupDict()
def get_geometry_type(self, table_name, geo_col):
- cursor = self.connection.cursor()
- try:
+ with self.connection.cursor() as cursor:
# Querying the `geometry_columns` table to get additional metadata.
cursor.execute('SELECT coord_dimension, srid, geometry_type '
'FROM geometry_columns '
@@ -55,9 +54,6 @@ class SpatiaLiteIntrospection(DatabaseIntrospection):
field_params['srid'] = srid
if (isinstance(dim, str) and 'Z' in dim) or dim == 3:
field_params['dim'] = 3
- finally:
- cursor.close()
-
return field_type, field_params
def get_constraints(self, cursor, table_name):
diff --git a/django/db/backends/base/base.py b/django/db/backends/base/base.py
index 468eb16e14..53c3c30063 100644
--- a/django/db/backends/base/base.py
+++ b/django/db/backends/base/base.py
@@ -573,11 +573,10 @@ class BaseDatabaseWrapper:
Provide a cursor: with self.temporary_connection() as cursor: ...
"""
must_close = self.connection is None
- cursor = self.cursor()
try:
- yield cursor
+ with self.cursor() as cursor:
+ yield cursor
finally:
- cursor.close()
if must_close:
self.close()
diff --git a/django/db/backends/base/introspection.py b/django/db/backends/base/introspection.py
index 154ae22bf1..8fe8966a21 100644
--- a/django/db/backends/base/introspection.py
+++ b/django/db/backends/base/introspection.py
@@ -116,21 +116,20 @@ class BaseDatabaseIntrospection:
from django.db import router
sequence_list = []
- cursor = self.connection.cursor()
-
- for app_config in apps.get_app_configs():
- for model in router.get_migratable_models(app_config, self.connection.alias):
- if not model._meta.managed:
- continue
- if model._meta.swapped:
- continue
- sequence_list.extend(self.get_sequences(cursor, model._meta.db_table, model._meta.local_fields))
- for f in model._meta.local_many_to_many:
- # If this is an m2m using an intermediate table,
- # we don't need to reset the sequence.
- if f.remote_field.through is None:
- sequence = self.get_sequences(cursor, f.m2m_db_table())
- sequence_list.extend(sequence or [{'table': f.m2m_db_table(), 'column': None}])
+ with self.connection.cursor() as cursor:
+ for app_config in apps.get_app_configs():
+ for model in router.get_migratable_models(app_config, self.connection.alias):
+ if not model._meta.managed:
+ continue
+ if model._meta.swapped:
+ continue
+ sequence_list.extend(self.get_sequences(cursor, model._meta.db_table, model._meta.local_fields))
+ for f in model._meta.local_many_to_many:
+ # If this is an m2m using an intermediate table,
+ # we don't need to reset the sequence.
+ if f.remote_field.through is None:
+ sequence = self.get_sequences(cursor, f.m2m_db_table())
+ sequence_list.extend(sequence or [{'table': f.m2m_db_table(), 'column': None}])
return sequence_list
def get_sequences(self, cursor, table_name, table_fields=()):
diff --git a/django/db/backends/mysql/base.py b/django/db/backends/mysql/base.py
index abf8f55736..6b82afc45d 100644
--- a/django/db/backends/mysql/base.py
+++ b/django/db/backends/mysql/base.py
@@ -294,36 +294,37 @@ class DatabaseWrapper(BaseDatabaseWrapper):
Backends can override this method if they can more directly apply
constraint checking (e.g. via "SET CONSTRAINTS ALL IMMEDIATE")
"""
- cursor = self.cursor()
- if table_names is None:
- table_names = self.introspection.table_names(cursor)
- for table_name in table_names:
- primary_key_column_name = self.introspection.get_primary_key_column(cursor, table_name)
- if not primary_key_column_name:
- continue
- key_columns = self.introspection.get_key_columns(cursor, table_name)
- for column_name, referenced_table_name, referenced_column_name in key_columns:
- cursor.execute(
- """
- SELECT REFERRING.`%s`, REFERRING.`%s` FROM `%s` as REFERRING
- LEFT JOIN `%s` as REFERRED
- ON (REFERRING.`%s` = REFERRED.`%s`)
- WHERE REFERRING.`%s` IS NOT NULL AND REFERRED.`%s` IS NULL
- """ % (
- primary_key_column_name, column_name, table_name,
- referenced_table_name, column_name, referenced_column_name,
- column_name, referenced_column_name,
- )
- )
- for bad_row in cursor.fetchall():
- raise utils.IntegrityError(
- "The row in table '%s' with primary key '%s' has an invalid "
- "foreign key: %s.%s contains a value '%s' that does not have a corresponding value in %s.%s."
- % (
- table_name, bad_row[0], table_name, column_name,
- bad_row[1], referenced_table_name, referenced_column_name,
+ with self.cursor() as cursor:
+ if table_names is None:
+ table_names = self.introspection.table_names(cursor)
+ for table_name in table_names:
+ primary_key_column_name = self.introspection.get_primary_key_column(cursor, table_name)
+ if not primary_key_column_name:
+ continue
+ key_columns = self.introspection.get_key_columns(cursor, table_name)
+ for column_name, referenced_table_name, referenced_column_name in key_columns:
+ cursor.execute(
+ """
+ SELECT REFERRING.`%s`, REFERRING.`%s` FROM `%s` as REFERRING
+ LEFT JOIN `%s` as REFERRED
+ ON (REFERRING.`%s` = REFERRED.`%s`)
+ WHERE REFERRING.`%s` IS NOT NULL AND REFERRED.`%s` IS NULL
+ """ % (
+ primary_key_column_name, column_name, table_name,
+ referenced_table_name, column_name, referenced_column_name,
+ column_name, referenced_column_name,
)
)
+ for bad_row in cursor.fetchall():
+ raise utils.IntegrityError(
+ "The row in table '%s' with primary key '%s' has an invalid "
+ "foreign key: %s.%s contains a value '%s' that does not "
+ "have a corresponding value in %s.%s."
+ % (
+ table_name, bad_row[0], table_name, column_name,
+ bad_row[1], referenced_table_name, referenced_column_name,
+ )
+ )
def is_usable(self):
try:
diff --git a/django/db/backends/oracle/creation.py b/django/db/backends/oracle/creation.py
index fe053c54f7..aa57e6a6ab 100644
--- a/django/db/backends/oracle/creation.py
+++ b/django/db/backends/oracle/creation.py
@@ -30,75 +30,72 @@ class DatabaseCreation(BaseDatabaseCreation):
def _create_test_db(self, verbosity=1, autoclobber=False, keepdb=False):
parameters = self._get_test_db_params()
- cursor = self._maindb_connection.cursor()
- if self._test_database_create():
- try:
- self._execute_test_db_creation(cursor, parameters, verbosity, keepdb)
- except Exception as e:
- if 'ORA-01543' not in str(e):
- # All errors except "tablespace already exists" cancel tests
- sys.stderr.write("Got an error creating the test database: %s\n" % e)
- sys.exit(2)
- if not autoclobber:
- confirm = input(
- "It appears the test database, %s, already exists. "
- "Type 'yes' to delete it, or 'no' to cancel: " % parameters['user'])
- if autoclobber or confirm == 'yes':
- if verbosity >= 1:
- print("Destroying old test database for alias '%s'..." % self.connection.alias)
- try:
- self._execute_test_db_destruction(cursor, parameters, verbosity)
- except DatabaseError as e:
- if 'ORA-29857' in str(e):
- self._handle_objects_preventing_db_destruction(cursor, parameters,
- verbosity, autoclobber)
- else:
- # Ran into a database error that isn't about leftover objects in the tablespace
+ with self._maindb_connection.cursor() as cursor:
+ if self._test_database_create():
+ try:
+ self._execute_test_db_creation(cursor, parameters, verbosity, keepdb)
+ except Exception as e:
+ if 'ORA-01543' not in str(e):
+ # All errors except "tablespace already exists" cancel tests
+ sys.stderr.write("Got an error creating the test database: %s\n" % e)
+ sys.exit(2)
+ if not autoclobber:
+ confirm = input(
+ "It appears the test database, %s, already exists. "
+ "Type 'yes' to delete it, or 'no' to cancel: " % parameters['user'])
+ if autoclobber or confirm == 'yes':
+ if verbosity >= 1:
+ print("Destroying old test database for alias '%s'..." % self.connection.alias)
+ try:
+ self._execute_test_db_destruction(cursor, parameters, verbosity)
+ except DatabaseError as e:
+ if 'ORA-29857' in str(e):
+ self._handle_objects_preventing_db_destruction(cursor, parameters,
+ verbosity, autoclobber)
+ else:
+ # Ran into a database error that isn't about leftover objects in the tablespace
+ sys.stderr.write("Got an error destroying the old test database: %s\n" % e)
+ sys.exit(2)
+ except Exception as e:
sys.stderr.write("Got an error destroying the old test database: %s\n" % e)
sys.exit(2)
- except Exception as e:
- sys.stderr.write("Got an error destroying the old test database: %s\n" % e)
- sys.exit(2)
- try:
- self._execute_test_db_creation(cursor, parameters, verbosity, keepdb)
- except Exception as e:
- sys.stderr.write("Got an error recreating the test database: %s\n" % e)
- sys.exit(2)
- else:
- print("Tests cancelled.")
- sys.exit(1)
+ try:
+ self._execute_test_db_creation(cursor, parameters, verbosity, keepdb)
+ except Exception as e:
+ sys.stderr.write("Got an error recreating the test database: %s\n" % e)
+ sys.exit(2)
+ else:
+ print("Tests cancelled.")
+ sys.exit(1)
- if self._test_user_create():
- if verbosity >= 1:
- print("Creating test user...")
- try:
- self._create_test_user(cursor, parameters, verbosity, keepdb)
- except Exception as e:
- if 'ORA-01920' not in str(e):
- # All errors except "user already exists" cancel tests
- sys.stderr.write("Got an error creating the test user: %s\n" % e)
- sys.exit(2)
- if not autoclobber:
- confirm = input(
- "It appears the test user, %s, already exists. Type "
- "'yes' to delete it, or 'no' to cancel: " % parameters['user'])
- if autoclobber or confirm == 'yes':
- try:
- if verbosity >= 1:
- print("Destroying old test user...")
- self._destroy_test_user(cursor, parameters, verbosity)
- if verbosity >= 1:
- print("Creating test user...")
- self._create_test_user(cursor, parameters, verbosity, keepdb)
- except Exception as e:
- sys.stderr.write("Got an error recreating the test user: %s\n" % e)
+ if self._test_user_create():
+ if verbosity >= 1:
+ print("Creating test user...")
+ try:
+ self._create_test_user(cursor, parameters, verbosity, keepdb)
+ except Exception as e:
+ if 'ORA-01920' not in str(e):
+ # All errors except "user already exists" cancel tests
+ sys.stderr.write("Got an error creating the test user: %s\n" % e)
sys.exit(2)
- else:
- print("Tests cancelled.")
- sys.exit(1)
-
- # Cursor must be closed before closing connection.
- cursor.close()
+ if not autoclobber:
+ confirm = input(
+ "It appears the test user, %s, already exists. Type "
+ "'yes' to delete it, or 'no' to cancel: " % parameters['user'])
+ if autoclobber or confirm == 'yes':
+ try:
+ if verbosity >= 1:
+ print("Destroying old test user...")
+ self._destroy_test_user(cursor, parameters, verbosity)
+ if verbosity >= 1:
+ print("Creating test user...")
+ self._create_test_user(cursor, parameters, verbosity, keepdb)
+ except Exception as e:
+ sys.stderr.write("Got an error recreating the test user: %s\n" % e)
+ sys.exit(2)
+ else:
+ print("Tests cancelled.")
+ sys.exit(1)
self._maindb_connection.close() # done with main user -- test user and tablespaces created
self._switch_to_test_user(parameters)
return self.connection.settings_dict['NAME']
@@ -175,17 +172,15 @@ class DatabaseCreation(BaseDatabaseCreation):
self.connection.settings_dict['PASSWORD'] = self.connection.settings_dict['SAVED_PASSWORD']
self.connection.close()
parameters = self._get_test_db_params()
- cursor = self._maindb_connection.cursor()
- if self._test_user_create():
- if verbosity >= 1:
- print('Destroying test user...')
- self._destroy_test_user(cursor, parameters, verbosity)
- if self._test_database_create():
- if verbosity >= 1:
- print('Destroying test database tables...')
- self._execute_test_db_destruction(cursor, parameters, verbosity)
- # Cursor must be closed before closing connection.
- cursor.close()
+ with self._maindb_connection.cursor() as cursor:
+ if self._test_user_create():
+ if verbosity >= 1:
+ print('Destroying test user...')
+ self._destroy_test_user(cursor, parameters, verbosity)
+ if self._test_database_create():
+ if verbosity >= 1:
+ print('Destroying test database tables...')
+ self._execute_test_db_destruction(cursor, parameters, verbosity)
self._maindb_connection.close()
def _execute_test_db_creation(self, cursor, parameters, verbosity, keepdb=False):
diff --git a/django/db/backends/sqlite3/base.py b/django/db/backends/sqlite3/base.py
index 40b205cf30..13f9a575e2 100644
--- a/django/db/backends/sqlite3/base.py
+++ b/django/db/backends/sqlite3/base.py
@@ -237,37 +237,37 @@ class DatabaseWrapper(BaseDatabaseWrapper):
Backends can override this method if they can more directly apply
constraint checking (e.g. via "SET CONSTRAINTS ALL IMMEDIATE")
"""
- cursor = self.cursor()
- if table_names is None:
- table_names = self.introspection.table_names(cursor)
- for table_name in table_names:
- primary_key_column_name = self.introspection.get_primary_key_column(cursor, table_name)
- if not primary_key_column_name:
- continue
- key_columns = self.introspection.get_key_columns(cursor, table_name)
- for column_name, referenced_table_name, referenced_column_name in key_columns:
- cursor.execute(
- """
- SELECT REFERRING.`%s`, REFERRING.`%s` FROM `%s` as REFERRING
- LEFT JOIN `%s` as REFERRED
- ON (REFERRING.`%s` = REFERRED.`%s`)
- WHERE REFERRING.`%s` IS NOT NULL AND REFERRED.`%s` IS NULL
- """
- % (
- primary_key_column_name, column_name, table_name,
- referenced_table_name, column_name, referenced_column_name,
- column_name, referenced_column_name,
- )
- )
- for bad_row in cursor.fetchall():
- raise utils.IntegrityError(
- "The row in table '%s' with primary key '%s' has an "
- "invalid foreign key: %s.%s contains a value '%s' that "
- "does not have a corresponding value in %s.%s." % (
- table_name, bad_row[0], table_name, column_name,
- bad_row[1], referenced_table_name, referenced_column_name,
+ with self.cursor() as cursor:
+ if table_names is None:
+ table_names = self.introspection.table_names(cursor)
+ for table_name in table_names:
+ primary_key_column_name = self.introspection.get_primary_key_column(cursor, table_name)
+ if not primary_key_column_name:
+ continue
+ key_columns = self.introspection.get_key_columns(cursor, table_name)
+ for column_name, referenced_table_name, referenced_column_name in key_columns:
+ cursor.execute(
+ """
+ SELECT REFERRING.`%s`, REFERRING.`%s` FROM `%s` as REFERRING
+ LEFT JOIN `%s` as REFERRED
+ ON (REFERRING.`%s` = REFERRED.`%s`)
+ WHERE REFERRING.`%s` IS NOT NULL AND REFERRED.`%s` IS NULL
+ """
+ % (
+ primary_key_column_name, column_name, table_name,
+ referenced_table_name, column_name, referenced_column_name,
+ column_name, referenced_column_name,
)
)
+ for bad_row in cursor.fetchall():
+ raise utils.IntegrityError(
+ "The row in table '%s' with primary key '%s' has an "
+ "invalid foreign key: %s.%s contains a value '%s' that "
+ "does not have a corresponding value in %s.%s." % (
+ table_name, bad_row[0], table_name, column_name,
+ bad_row[1], referenced_table_name, referenced_column_name,
+ )
+ )
def is_usable(self):
return True
diff --git a/django/db/migrations/executor.py b/django/db/migrations/executor.py
index ea7bc70db3..ebaf75634b 100644
--- a/django/db/migrations/executor.py
+++ b/django/db/migrations/executor.py
@@ -322,7 +322,8 @@ class MigrationExecutor:
apps = after_state.apps
found_create_model_migration = False
found_add_field_migration = False
- existing_table_names = self.connection.introspection.table_names(self.connection.cursor())
+ with self.connection.cursor() as cursor:
+ existing_table_names = self.connection.introspection.table_names(cursor)
# Make sure all create model and add field operations are done
for operation in migration.operations:
if isinstance(operation, migrations.CreateModel):
diff --git a/django/test/testcases.py b/django/test/testcases.py
index afab58f2dc..4c32c87da5 100644
--- a/django/test/testcases.py
+++ b/django/test/testcases.py
@@ -852,9 +852,9 @@ class TransactionTestCase(SimpleTestCase):
no_style(), conn.introspection.sequence_list())
if sql_list:
with transaction.atomic(using=db_name):
- cursor = conn.cursor()
- for sql in sql_list:
- cursor.execute(sql)
+ with conn.cursor() as cursor:
+ for sql in sql_list:
+ cursor.execute(sql)
def _fixture_setup(self):
for db_name in self._databases_names(include_mirrors=False):