Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 9dc4ba8

Browse files
Fixed #5461 -- Refactored the database backend code to use classes for the creation and introspection modules. Introduces a new validation module for DB-specific validation. This is a backwards incompatible change; see the wiki for details.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@8296 bcc190cf-cafb-0310-a4f2-bffc1f526a37
1 parent cec69eb commit 9dc4ba8

File tree

43 files changed

+1521
-1416
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+1521
-1416
lines changed
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
from django.test.utils import create_test_db
21

32
def create_spatial_db(test=True, verbosity=1, autoclobber=False):
43
if not test: raise NotImplementedError('This uses `create_test_db` from test/utils.py')
5-
create_test_db(verbosity, autoclobber)
4+
from django.db import connection
5+
connection.creation.create_test_db(verbosity, autoclobber)
Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
1-
from django.db.backends.oracle.creation import create_test_db
21

32
def create_spatial_db(test=True, verbosity=1, autoclobber=False):
43
"A wrapper over the Oracle `create_test_db` routine."
54
if not test: raise NotImplementedError('This uses `create_test_db` from db/backends/oracle/creation.py')
6-
from django.conf import settings
75
from django.db import connection
8-
create_test_db(settings, connection, verbosity, autoclobber)
6+
connection.creation.create_test_db(verbosity, autoclobber)

‎django/contrib/gis/db/backend/postgis/creation.py‎

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from django.conf import settings
22
from django.core.management import call_command
33
from django.db import connection
4-
from django.test.utils import_set_autocommit, TEST_DATABASE_PREFIX
4+
from django.db.backends.creation import TEST_DATABASE_PREFIX
55
import os, re, sys
66

77
def getstatusoutput(cmd):
@@ -38,9 +38,9 @@ def _create_with_cursor(db_name, verbosity=1, autoclobber=False):
3838
create_sql = 'CREATE DATABASE %s' % connection.ops.quote_name(db_name)
3939
if settings.DATABASE_USER:
4040
create_sql += ' OWNER %s' % settings.DATABASE_USER
41-
41+
4242
cursor = connection.cursor()
43-
_set_autocommit(connection)
43+
connection.creation.set_autocommit(connection)
4444

4545
try:
4646
# Trying to create the database first.
@@ -58,12 +58,12 @@ def _create_with_cursor(db_name, verbosity=1, autoclobber=False):
5858
else:
5959
raise Exception('Spatial Database Creation canceled.')
6060
foo = _create_with_cursor
61-
61+
6262
created_regex = re.compile(r'^createdb: database creation failed: ERROR: database ".+" already exists')
6363
def _create_with_shell(db_name, verbosity=1, autoclobber=False):
6464
"""
65-
If no spatial database already exists, then using a cursor will not work.
66-
Thus, a `createdb` command will be issued through the shell to bootstrap
65+
If no spatial database already exists, then using a cursor will not work.
66+
Thus, a `createdb` command will be issued through the shell to bootstrap
6767
creation of the spatial database.
6868
"""
6969

@@ -83,7 +83,7 @@ def _create_with_shell(db_name, verbosity=1, autoclobber=False):
8383
if verbosity >= 1: print 'Destroying old spatial database...'
8484
drop_cmd = 'dropdb %s%s' % (options, db_name)
8585
status, output = getstatusoutput(drop_cmd)
86-
if status != 0:
86+
if status != 0:
8787
raise Exception('Could not drop database %s: %s' % (db_name, output))
8888
if verbosity >= 1: print 'Creating new spatial database...'
8989
status, output = getstatusoutput(create_cmd)
@@ -102,10 +102,10 @@ def create_spatial_db(test=False, verbosity=1, autoclobber=False, interactive=Fa
102102
raise Exception('Spatial database creation only supported postgresql_psycopg2 platform.')
103103

104104
# Getting the spatial database name
105-
if test:
105+
if test:
106106
db_name = get_spatial_db(test=True)
107107
_create_with_cursor(db_name, verbosity=verbosity, autoclobber=autoclobber)
108-
else:
108+
else:
109109
db_name = get_spatial_db()
110110
_create_with_shell(db_name, verbosity=verbosity, autoclobber=autoclobber)
111111

@@ -125,7 +125,7 @@ def create_spatial_db(test=False, verbosity=1, autoclobber=False, interactive=Fa
125125

126126
# Syncing the database
127127
call_command('syncdb', verbosity=verbosity, interactive=interactive)
128-
128+
129129
def drop_db(db_name=False, test=False):
130130
"""
131131
Drops the given database (defaults to what is returned from
@@ -151,7 +151,7 @@ def get_cmd_options(db_name):
151151

152152
def get_spatial_db(test=False):
153153
"""
154-
Returns the name of the spatial database. The 'test' keyword may be set
154+
Returns the name of the spatial database. The 'test' keyword may be set
155155
to return the test spatial database name.
156156
"""
157157
if test:
@@ -167,13 +167,13 @@ def get_spatial_db(test=False):
167167

168168
def load_postgis_sql(db_name, verbosity=1):
169169
"""
170-
This routine loads up the PostGIS SQL files lwpostgis.sql and
170+
This routine loads up the PostGIS SQL files lwpostgis.sql and
171171
spatial_ref_sys.sql.
172172
"""
173173

174174
# Getting the path to the PostGIS SQL
175175
try:
176-
# POSTGIS_SQL_PATH may be placed in settings to tell GeoDjango where the
176+
# POSTGIS_SQL_PATH may be placed in settings to tell GeoDjango where the
177177
# PostGIS SQL files are located. This is especially useful on Win32
178178
# platforms since the output of pg_config looks like "C:/PROGRA~1/..".
179179
sql_path = settings.POSTGIS_SQL_PATH
@@ -193,7 +193,7 @@ def load_postgis_sql(db_name, verbosity=1):
193193
# Getting the psql command-line options, and command format.
194194
options = get_cmd_options(db_name)
195195
cmd_fmt = 'psql %s-f "%%s"' % options
196-
196+
197197
# Now trying to load up the PostGIS functions
198198
cmd = cmd_fmt % lwpostgis_file
199199
if verbosity >= 1: print cmd
@@ -211,8 +211,8 @@ def load_postgis_sql(db_name, verbosity=1):
211211
# Setting the permissions because on Windows platforms the owner
212212
# of the spatial_ref_sys and geometry_columns tables is always
213213
# the postgres user, regardless of how the db is created.
214-
if os.name == 'nt': set_permissions(db_name)
215-
214+
if os.name == 'nt': set_permissions(db_name)
215+
216216
def set_permissions(db_name):
217217
"""
218218
Sets the permissions on the given database to that of the user specified

‎django/contrib/gis/management/commands/inspectdb.py‎

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from django.contrib.gis.db.backend import SpatialBackend
88

99
class Command(InspectCommand):
10-
10+
1111
# Mapping from lower-case OGC type to the corresponding GeoDjango field.
1212
geofield_mapping = {'point' : 'PointField',
1313
'linestring' : 'LineStringField',
@@ -21,11 +21,11 @@ class Command(InspectCommand):
2121

2222
def geometry_columns(self):
2323
"""
24-
Returns a datastructure of metadata information associated with the
24+
Returns a datastructure of metadata information associated with the
2525
`geometry_columns` (or equivalent) table.
2626
"""
2727
# The `geo_cols` is a dictionary data structure that holds information
28-
# about any geographic columns in the database.
28+
# about any geographic columns in the database.
2929
geo_cols = {}
3030
def add_col(table, column, coldata):
3131
if table in geo_cols:
@@ -47,7 +47,7 @@ def add_col(table, column, coldata):
4747
elif SpatialBackend.name == 'mysql':
4848
# On MySQL have to get all table metadata before hand; this means walking through
4949
# each table and seeing if any column types are spatial. Can't detect this with
50-
# `cursor.description` (what the introspection module does) because all spatial types
50+
# `cursor.description` (what the introspection module does) because all spatial types
5151
# have the same integer type (255 for GEOMETRY).
5252
from django.db import connection
5353
cursor = connection.cursor()
@@ -67,13 +67,11 @@ def add_col(table, column, coldata):
6767

6868
def handle_inspection(self):
6969
"Overloaded from Django's version to handle geographic database tables."
70-
from django.db import connection, get_introspection_module
70+
from django.db import connection
7171
import keyword
7272

73-
introspection_module = get_introspection_module()
74-
7573
geo_cols = self.geometry_columns()
76-
74+
7775
table2model = lambda table_name: table_name.title().replace('_', '')
7876

7977
cursor = connection.cursor()
@@ -88,20 +86,20 @@ def handle_inspection(self):
8886
yield ''
8987
yield 'from django.contrib.gis.db import models'
9088
yield ''
91-
for table_name in introspection_module.get_table_list(cursor):
89+
for table_name in connection.introspection.get_table_list(cursor):
9290
# Getting the geographic table dictionary.
9391
geo_table = geo_cols.get(table_name, {})
9492

9593
yield 'class %s(models.Model):' % table2model(table_name)
9694
try:
97-
relations = introspection_module.get_relations(cursor, table_name)
95+
relations = connection.introspection.get_relations(cursor, table_name)
9896
except NotImplementedError:
9997
relations = {}
10098
try:
101-
indexes = introspection_module.get_indexes(cursor, table_name)
99+
indexes = connection.introspection.get_indexes(cursor, table_name)
102100
except NotImplementedError:
103101
indexes = {}
104-
for i, row in enumerate(introspection_module.get_table_description(cursor, table_name)):
102+
for i, row in enumerate(connection.introspection.get_table_description(cursor, table_name)):
105103
att_name, iatt_name = row[0].lower(), row[0]
106104
comment_notes = [] # Holds Field notes, to be displayed in a Python comment.
107105
extra_params = {} # Holds Field parameters such as 'db_column'.
@@ -133,12 +131,12 @@ def handle_inspection(self):
133131
if srid != 4326: extra_params['srid'] = srid
134132
else:
135133
try:
136-
field_type = introspection_module.DATA_TYPES_REVERSE[row[1]]
134+
field_type = connection.introspection.data_types_reverse[row[1]]
137135
except KeyError:
138136
field_type = 'TextField'
139137
comment_notes.append('This field type is a guess.')
140138

141-
# This is a hook for DATA_TYPES_REVERSE to return a tuple of
139+
# This is a hook for data_types_reverse to return a tuple of
142140
# (field_type, extra_params_dict).
143141
if type(field_type) is tuple:
144142
field_type, new_params = field_type

‎django/core/management/commands/dbshell.py‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@ class Command(NoArgsCommand):
66
requires_model_validation = False
77

88
def handle_noargs(self, **options):
9-
from django.db import runshell
10-
runshell()
9+
from django.db import connection
10+
connection.client.runshell()

‎django/core/management/commands/inspectdb.py‎

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,9 @@ def handle_noargs(self, **options):
1313
raise CommandError("Database inspection isn't supported for the currently selected database backend.")
1414

1515
def handle_inspection(self):
16-
from django.db import connection, get_introspection_module
16+
from django.db import connection
1717
import keyword
1818

19-
introspection_module = get_introspection_module()
20-
2119
table2model = lambda table_name: table_name.title().replace('_', '')
2220

2321
cursor = connection.cursor()
@@ -32,17 +30,17 @@ def handle_inspection(self):
3230
yield ''
3331
yield 'from django.db import models'
3432
yield ''
35-
for table_name in introspection_module.get_table_list(cursor):
33+
for table_name in connection.introspection.get_table_list(cursor):
3634
yield 'class %s(models.Model):' % table2model(table_name)
3735
try:
38-
relations = introspection_module.get_relations(cursor, table_name)
36+
relations = connection.introspection.get_relations(cursor, table_name)
3937
except NotImplementedError:
4038
relations = {}
4139
try:
42-
indexes = introspection_module.get_indexes(cursor, table_name)
40+
indexes = connection.introspection.get_indexes(cursor, table_name)
4341
except NotImplementedError:
4442
indexes = {}
45-
for i, row in enumerate(introspection_module.get_table_description(cursor, table_name)):
43+
for i, row in enumerate(connection.introspection.get_table_description(cursor, table_name)):
4644
att_name = row[0].lower()
4745
comment_notes = [] # Holds Field notes, to be displayed in a Python comment.
4846
extra_params = {} # Holds Field parameters such as 'db_column'.
@@ -65,7 +63,7 @@ def handle_inspection(self):
6563
extra_params['db_column'] = att_name
6664
else:
6765
try:
68-
field_type = introspection_module.DATA_TYPES_REVERSE[row[1]]
66+
field_type = connection.introspection.data_types_reverse[row[1]]
6967
except KeyError:
7068
field_type = 'TextField'
7169
comment_notes.append('This field type is a guess.')

‎django/core/management/commands/syncdb.py‎

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ class Command(NoArgsCommand):
2121
def handle_noargs(self, **options):
2222
from django.db import connection, transaction, models
2323
from django.conf import settings
24-
from django.core.management.sql import table_names, installed_models, sql_model_create, sql_for_pending_references, many_to_many_sql_for_model, custom_sql_for_model, sql_indexes_for_model, emit_post_sync_signal
24+
from django.core.management.sql import custom_sql_for_model, emit_post_sync_signal
2525

2626
verbosity = int(options.get('verbosity', 1))
2727
interactive = options.get('interactive')
@@ -50,16 +50,9 @@ def handle_noargs(self, **options):
5050

5151
cursor = connection.cursor()
5252

53-
if connection.features.uses_case_insensitive_names:
54-
table_name_converter = lambda x: x.upper()
55-
else:
56-
table_name_converter = lambda x: x
57-
# Get a list of all existing database tables, so we know what needs to
58-
# be added.
59-
tables = [table_name_converter(name) for name in table_names()]
60-
6153
# Get a list of already installed *models* so that references work right.
62-
seen_models = installed_models(tables)
54+
tables = connection.introspection.table_names()
55+
seen_models = connection.introspection.installed_models(tables)
6356
created_models = set()
6457
pending_references = {}
6558

@@ -71,21 +64,21 @@ def handle_noargs(self, **options):
7164
# Create the model's database table, if it doesn't already exist.
7265
if verbosity >= 2:
7366
print "Processing %s.%s model" % (app_name, model._meta.object_name)
74-
if table_name_converter(model._meta.db_table) in tables:
67+
if connection.introspection.table_name_converter(model._meta.db_table) in tables:
7568
continue
76-
sql, references = sql_model_create(model, self.style, seen_models)
69+
sql, references = connection.creation.sql_create_model(model, self.style, seen_models)
7770
seen_models.add(model)
7871
created_models.add(model)
7972
for refto, refs in references.items():
8073
pending_references.setdefault(refto, []).extend(refs)
8174
if refto in seen_models:
82-
sql.extend(sql_for_pending_references(refto, self.style, pending_references))
83-
sql.extend(sql_for_pending_references(model, self.style, pending_references))
75+
sql.extend(connection.creation.sql_for_pending_references(refto, self.style, pending_references))
76+
sql.extend(connection.creation.sql_for_pending_references(model, self.style, pending_references))
8477
if verbosity >= 1:
8578
print "Creating table %s" % model._meta.db_table
8679
for statement in sql:
8780
cursor.execute(statement)
88-
tables.append(table_name_converter(model._meta.db_table))
81+
tables.append(connection.introspection.table_name_converter(model._meta.db_table))
8982

9083
# Create the m2m tables. This must be done after all tables have been created
9184
# to ensure that all referred tables will exist.
@@ -94,7 +87,7 @@ def handle_noargs(self, **options):
9487
model_list = models.get_models(app)
9588
for model in model_list:
9689
if model in created_models:
97-
sql = many_to_many_sql_for_model(model, self.style)
90+
sql = connection.creation.sql_for_many_to_many(model, self.style)
9891
if sql:
9992
if verbosity >= 2:
10093
print "Creating many-to-many tables for %s.%s model" % (app_name, model._meta.object_name)
@@ -140,7 +133,7 @@ def handle_noargs(self, **options):
140133
app_name = app.__name__.split('.')[-2]
141134
for model in models.get_models(app):
142135
if model in created_models:
143-
index_sql = sql_indexes_for_model(model, self.style)
136+
index_sql = connection.creation.sql_indexes_for_model(model, self.style)
144137
if index_sql:
145138
if verbosity >= 1:
146139
print "Installing index for %s.%s model" % (app_name, model._meta.object_name)

‎django/core/management/commands/testserver.py‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,13 @@ class Command(BaseCommand):
1818

1919
def handle(self, *fixture_labels, **options):
2020
from django.core.management import call_command
21-
from django.test.utils import create_test_db
21+
from django.db import connection
2222

2323
verbosity = int(options.get('verbosity', 1))
2424
addrport = options.get('addrport')
2525

2626
# Create a test database.
27-
db_name = create_test_db(verbosity=verbosity)
27+
db_name = connection.creation.create_test_db(verbosity=verbosity)
2828

2929
# Import the fixture data into the test database.
3030
call_command('loaddata', *fixture_labels, **{'verbosity': verbosity})

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /