1
0
mirror of https://github.com/django/django.git synced 2025-07-05 10:19:20 +00:00

[multi-db] Integrated drop table generation from ansi sql, updated model

connection name access to use django.db.model_connection_name().


git-svn-id: http://code.djangoproject.com/svn/django/branches/multiple-db-support@3389 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Jason Pellerin 2006-07-19 18:59:50 +00:00
parent 58b24acdf4
commit c705f3a573

View File

@ -49,9 +49,6 @@ def disable_termcolors():
if sys.platform == 'win32' or sys.platform == 'Pocket PC' or not sys.stdout.isatty(): if sys.platform == 'win32' or sys.platform == 'Pocket PC' or not sys.stdout.isatty():
disable_termcolors() disable_termcolors()
# singleton representing the default connection
_default = object()
def _is_valid_dir_name(s): def _is_valid_dir_name(s):
return bool(re.search(r'^\w+$', s)) return bool(re.search(r'^\w+$', s))
@ -86,7 +83,7 @@ def get_version():
def get_sql_create(app): def get_sql_create(app):
"Returns a list of the CREATE TABLE SQL statements for the given app." "Returns a list of the CREATE TABLE SQL statements for the given app."
from django.db import models from django.db import models, model_connection_name
# final output will be divided by comments into sections for each # final output will be divided by comments into sections for each
# named connection, if there are any named connections # named connection, if there are any named connections
@ -97,10 +94,10 @@ def get_sql_create(app):
app_models = models.get_models(app, creation_order=True) app_models = models.get_models(app, creation_order=True)
for klass in app_models: for klass in app_models:
opts = klass._meta opts = klass._meta
connection_name = opts.db_connection or _default connection_name = model_connection_name(klass)
output = connection_output.setdefault(connection_name, []) output = connection_output.setdefault(connection_name, [])
info = opts.connection_info db = klass._default_manager.db
creation = info.get_creation_module() creation = db.get_creation_module()
data_types = creation.DATA_TYPES data_types = creation.DATA_TYPES
if not data_types: if not data_types:
# This must be the "dummy" database backend, which means the user # This must be the "dummy" database backend, which means the user
@ -153,73 +150,33 @@ get_sql_create.args = APP_ARGS
def get_sql_delete(app): def get_sql_delete(app):
"Returns a list of the DROP TABLE SQL statements for the given app." "Returns a list of the DROP TABLE SQL statements for the given app."
from django.db import backend, connection, models, get_introspection_module from django.db import models, model_connection_name
introspection = get_introspection_module()
connection_output = {}
# This should work even if a connecton isn't available final_output = []
try: app_models = models.get_models(app, creation_order=True)
cursor = connection.cursor()
except:
cursor = None
# Figure out which tables already exist
if cursor:
table_names = introspection.get_table_list(cursor)
else:
table_names = []
output = []
# Output DROP TABLE statements for standard application tables.
to_delete = set()
references_to_delete = {}
app_models = models.get_models(app)
for klass in app_models: for klass in app_models:
if cursor and klass._meta.db_table in table_names: db = klass._default_manager.db
# The table exists, so it needs to be dropped connection = db.connection
opts = klass._meta try:
for f in opts.fields: cursor = connection.cursor()
if f.rel and f.rel.to not in to_delete: except:
references_to_delete.setdefault(f.rel.to, []).append( (klass, f) ) cursor = None
builder = db.get_creation_module().builder
to_delete.add(klass) connection_name = model_connection_name(klass)
output = connection_output.setdefault(connection_name, [])
for klass in app_models: output.extend(map(str,
if cursor and klass._meta.db_table in table_names: builder.get_drop_table(klass,
# Drop the table now cascade=True, style=style)))
output.append('%s %s;' % (style.SQL_KEYWORD('DROP TABLE'), if cursor:
style.SQL_TABLE(backend.quote_name(klass._meta.db_table)))) # Close database connection explicitly, in case this
if backend.supports_constraints and references_to_delete.has_key(klass): # output is being piped directly into a database client,
for rel_class, f in references_to_delete[klass]: # to avoid locking issues.
table = rel_class._meta.db_table cursor.close()
col = f.column connection.close()
r_table = klass._meta.db_table # Reverse it, to deal with table dependencies.
r_col = klass._meta.get_field(f.rel.field_name).column final_output = _collate(connection_output, reverse=True)
output.append('%s %s %s %s;' % \ return final_output
(style.SQL_KEYWORD('ALTER TABLE'),
style.SQL_TABLE(backend.quote_name(table)),
style.SQL_KEYWORD(backend.get_drop_foreignkey_sql()),
style.SQL_FIELD(backend.quote_name("%s_referencing_%s_%s" % (col, r_table, r_col)))))
del references_to_delete[klass]
# Output DROP TABLE statements for many-to-many tables.
for klass in app_models:
opts = klass._meta
for f in opts.many_to_many:
if cursor and f.m2m_db_table() in table_names:
output.append("%s %s;" % (style.SQL_KEYWORD('DROP TABLE'),
style.SQL_TABLE(backend.quote_name(f.m2m_db_table()))))
app_label = app_models[0]._meta.app_label
# Close database connection explicitly, in case this output is being piped
# directly into a database client, to avoid locking issues.
if cursor:
cursor.close()
connection.close()
return output[::-1] # Reverse it, to deal with table dependencies.
get_sql_delete.help_doc = "Prints the DROP TABLE SQL statements for the given app name(s)." get_sql_delete.help_doc = "Prints the DROP TABLE SQL statements for the given app name(s)."
get_sql_delete.args = APP_ARGS get_sql_delete.args = APP_ARGS
@ -231,16 +188,16 @@ get_sql_reset.args = APP_ARGS
def get_sql_initial_data(app): def get_sql_initial_data(app):
"Returns a list of the initial INSERT SQL statements for the given app." "Returns a list of the initial INSERT SQL statements for the given app."
from django.db import model_connection_name
from django.db.models import get_models from django.db.models import get_models
connection_output = {} connection_output = {}
app_models = get_models(app) app_models = get_models(app)
for klass in app_models: for klass in app_models:
opts = klass._meta opts = klass._meta
connection_name = opts.db_connection or _default connection_name = model_connection_name(klass)
output = connection_output.setdefault(connection_name, []) output = connection_output.setdefault(connection_name, [])
info = opts.connection_info builder = klass._default_manager.db.get_creation_module().builder
builder = info.get_creation_module().builder
output.extend(builder.get_initialdata(klass)) output.extend(builder.get_initialdata(klass))
return _collate(connection_output) return _collate(connection_output)
@ -276,15 +233,15 @@ get_sql_sequence_reset.args = APP_ARGS
def get_sql_indexes(app): def get_sql_indexes(app):
"Returns a list of the CREATE INDEX SQL statements for the given app." "Returns a list of the CREATE INDEX SQL statements for the given app."
from django.db import model_connection_name
from django.db.models import get_models from django.db.models import get_models
connection_output = {} connection_output = {}
for klass in get_models(app): for klass in get_models(app):
opts = klass._meta opts = klass._meta
connection_name = opts.db_connection or _default connection_name = model_connection_name(klass)
output = connection_output.setdefault(connection_name, []) output = connection_output.setdefault(connection_name, [])
info = opts.connection_info builder = klass._default_manager.db.get_creation_module().builder
builder = info.get_creation_module().builder
output.extend(map(str, builder.get_create_indexes(klass, style))) output.extend(map(str, builder.get_create_indexes(klass, style)))
return _collate(connection_output) return _collate(connection_output)
@ -297,12 +254,15 @@ def get_sql_all(app):
get_sql_all.help_doc = "Prints the CREATE TABLE, initial-data and CREATE INDEX SQL statements for the given model module name(s)." get_sql_all.help_doc = "Prints the CREATE TABLE, initial-data and CREATE INDEX SQL statements for the given model module name(s)."
get_sql_all.args = APP_ARGS get_sql_all.args = APP_ARGS
def _collate(connection_output): def _collate(connection_output, reverse=False):
from django.db import _default
final_output = [] final_output = []
if len(connection_output.keys()) == 1: if len(connection_output.keys()) == 1:
# all for the default connection # all for the default connection
for statements in connection_output.values(): for statements in connection_output.values():
final_output.extend(statements) final_output.extend(statements)
if reverse:
final_output.reverse()
else: else:
for connection_name, statements in connection_output.items(): for connection_name, statements in connection_output.items():
if not statements: if not statements:
@ -310,6 +270,8 @@ def _collate(connection_output):
if connection_name is _default: if connection_name is _default:
connection_name = '(default)' connection_name = '(default)'
final_output.append(' -- The following statements are for connection: %s' % connection_name) final_output.append(' -- The following statements are for connection: %s' % connection_name)
if reverse:
statements.reverse()
final_output.extend(statements) final_output.extend(statements)
final_output.append(' -- END statements for %s\n' % final_output.append(' -- END statements for %s\n' %
connection_name) connection_name)