Removed support for syncing apps without migrations per deprecation timeline.
Kept support for creating models without migrations when running tests (especially for Django's test suite).
This commit is contained in:
parent
9704b0a82e
commit
7e8cf74dc7
|
@ -232,8 +232,7 @@ class ManagementUtility(object):
|
||||||
elif cwords[0] in subcommands and cwords[0] != 'help':
|
elif cwords[0] in subcommands and cwords[0] != 'help':
|
||||||
subcommand_cls = self.fetch_command(cwords[0])
|
subcommand_cls = self.fetch_command(cwords[0])
|
||||||
# special case: add the names of installed apps to options
|
# special case: add the names of installed apps to options
|
||||||
if cwords[0] in ('dumpdata', 'sql', 'sqlall', 'sqlclear',
|
if cwords[0] in ('dumpdata', 'sqlmigrate', 'sqlsequencereset', 'test'):
|
||||||
'sqlindexes', 'sqlmigrate', 'sqlsequencereset', 'test'):
|
|
||||||
try:
|
try:
|
||||||
app_configs = apps.get_app_configs()
|
app_configs = apps.get_app_configs()
|
||||||
# Get the last part of the dotted path as the app name.
|
# Get the last part of the dotted path as the app name.
|
||||||
|
|
|
@ -93,14 +93,12 @@ class Command(BaseCommand):
|
||||||
)
|
)
|
||||||
|
|
||||||
# If they supplied command line arguments, work out what they mean.
|
# If they supplied command line arguments, work out what they mean.
|
||||||
run_syncdb = False
|
|
||||||
target_app_labels_only = True
|
target_app_labels_only = True
|
||||||
if options['app_label'] and options['migration_name']:
|
if options['app_label'] and options['migration_name']:
|
||||||
app_label, migration_name = options['app_label'], options['migration_name']
|
app_label, migration_name = options['app_label'], options['migration_name']
|
||||||
if app_label not in executor.loader.migrated_apps:
|
if app_label not in executor.loader.migrated_apps:
|
||||||
raise CommandError(
|
raise CommandError(
|
||||||
"App '%s' does not have migrations (you cannot selectively "
|
"App '%s' does not have migrations." % app_label
|
||||||
"sync unmigrated apps)" % app_label
|
|
||||||
)
|
)
|
||||||
if migration_name == "zero":
|
if migration_name == "zero":
|
||||||
targets = [(app_label, None)]
|
targets = [(app_label, None)]
|
||||||
|
@ -122,20 +120,19 @@ class Command(BaseCommand):
|
||||||
app_label = options['app_label']
|
app_label = options['app_label']
|
||||||
if app_label not in executor.loader.migrated_apps:
|
if app_label not in executor.loader.migrated_apps:
|
||||||
raise CommandError(
|
raise CommandError(
|
||||||
"App '%s' does not have migrations (you cannot selectively "
|
"App '%s' does not have migrations." % app_label
|
||||||
"sync unmigrated apps)" % app_label
|
|
||||||
)
|
)
|
||||||
targets = [key for key in executor.loader.graph.leaf_nodes() if key[0] == app_label]
|
targets = [key for key in executor.loader.graph.leaf_nodes() if key[0] == app_label]
|
||||||
else:
|
else:
|
||||||
targets = executor.loader.graph.leaf_nodes()
|
targets = executor.loader.graph.leaf_nodes()
|
||||||
run_syncdb = True
|
|
||||||
|
|
||||||
plan = executor.migration_plan(targets)
|
plan = executor.migration_plan(targets)
|
||||||
|
run_syncdb = options.get('run_syncdb') and executor.loader.unmigrated_apps
|
||||||
|
|
||||||
# Print some useful info
|
# Print some useful info
|
||||||
if self.verbosity >= 1:
|
if self.verbosity >= 1:
|
||||||
self.stdout.write(self.style.MIGRATE_HEADING("Operations to perform:"))
|
self.stdout.write(self.style.MIGRATE_HEADING("Operations to perform:"))
|
||||||
if run_syncdb and executor.loader.unmigrated_apps:
|
if run_syncdb:
|
||||||
self.stdout.write(
|
self.stdout.write(
|
||||||
self.style.MIGRATE_LABEL(" Synchronize unmigrated apps: ") +
|
self.style.MIGRATE_LABEL(" Synchronize unmigrated apps: ") +
|
||||||
(", ".join(executor.loader.unmigrated_apps))
|
(", ".join(executor.loader.unmigrated_apps))
|
||||||
|
@ -159,7 +156,7 @@ class Command(BaseCommand):
|
||||||
emit_pre_migrate_signal(self.verbosity, self.interactive, connection.alias)
|
emit_pre_migrate_signal(self.verbosity, self.interactive, connection.alias)
|
||||||
|
|
||||||
# Run the syncdb phase.
|
# Run the syncdb phase.
|
||||||
if run_syncdb and executor.loader.unmigrated_apps:
|
if run_syncdb:
|
||||||
if self.verbosity >= 1:
|
if self.verbosity >= 1:
|
||||||
self.stdout.write(self.style.MIGRATE_HEADING("Synchronizing apps without migrations:"))
|
self.stdout.write(self.style.MIGRATE_HEADING("Synchronizing apps without migrations:"))
|
||||||
self.sync_apps(connection, executor.loader.unmigrated_apps)
|
self.sync_apps(connection, executor.loader.unmigrated_apps)
|
||||||
|
|
|
@ -1,24 +0,0 @@
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
from django.core.management.base import AppCommand
|
|
||||||
from django.core.management.sql import sql_create
|
|
||||||
from django.db import connections, DEFAULT_DB_ALIAS
|
|
||||||
|
|
||||||
|
|
||||||
class Command(AppCommand):
|
|
||||||
help = "Prints the CREATE TABLE SQL statements for the given app name(s)."
|
|
||||||
|
|
||||||
output_transaction = True
|
|
||||||
|
|
||||||
def add_arguments(self, parser):
|
|
||||||
super(Command, self).add_arguments(parser)
|
|
||||||
parser.add_argument('--database', default=DEFAULT_DB_ALIAS,
|
|
||||||
help='Nominates a database to print the SQL for. Defaults to the '
|
|
||||||
'"default" database.')
|
|
||||||
|
|
||||||
def handle_app_config(self, app_config, **options):
|
|
||||||
if app_config.models_module is None:
|
|
||||||
return
|
|
||||||
connection = connections[options['database']]
|
|
||||||
statements = sql_create(app_config, self.style, connection)
|
|
||||||
return '\n'.join(statements)
|
|
|
@ -1,24 +0,0 @@
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
from django.core.management.base import AppCommand
|
|
||||||
from django.core.management.sql import sql_all
|
|
||||||
from django.db import connections, DEFAULT_DB_ALIAS
|
|
||||||
|
|
||||||
|
|
||||||
class Command(AppCommand):
|
|
||||||
help = "Prints the CREATE TABLE and CREATE INDEX SQL statements for the given model module name(s)."
|
|
||||||
|
|
||||||
output_transaction = True
|
|
||||||
|
|
||||||
def add_arguments(self, parser):
|
|
||||||
super(Command, self).add_arguments(parser)
|
|
||||||
parser.add_argument('--database', default=DEFAULT_DB_ALIAS,
|
|
||||||
help='Nominates a database to print the SQL for. Defaults to the '
|
|
||||||
'"default" database.')
|
|
||||||
|
|
||||||
def handle_app_config(self, app_config, **options):
|
|
||||||
if app_config.models_module is None:
|
|
||||||
return
|
|
||||||
connection = connections[options['database']]
|
|
||||||
statements = sql_all(app_config, self.style, connection)
|
|
||||||
return '\n'.join(statements)
|
|
|
@ -1,24 +0,0 @@
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
from django.core.management.base import AppCommand
|
|
||||||
from django.core.management.sql import sql_delete
|
|
||||||
from django.db import connections, DEFAULT_DB_ALIAS
|
|
||||||
|
|
||||||
|
|
||||||
class Command(AppCommand):
|
|
||||||
help = "Prints the DROP TABLE SQL statements for the given app name(s)."
|
|
||||||
|
|
||||||
output_transaction = True
|
|
||||||
|
|
||||||
def add_arguments(self, parser):
|
|
||||||
super(Command, self).add_arguments(parser)
|
|
||||||
parser.add_argument('--database', default=DEFAULT_DB_ALIAS,
|
|
||||||
help='Nominates a database to print the SQL for. Defaults to the '
|
|
||||||
'"default" database.')
|
|
||||||
|
|
||||||
def handle_app_config(self, app_config, **options):
|
|
||||||
if app_config.models_module is None:
|
|
||||||
return
|
|
||||||
connection = connections[options['database']]
|
|
||||||
statements = sql_delete(app_config, self.style, connection)
|
|
||||||
return '\n'.join(statements)
|
|
|
@ -1,24 +0,0 @@
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
from django.core.management.base import AppCommand
|
|
||||||
from django.core.management.sql import sql_destroy_indexes
|
|
||||||
from django.db import connections, DEFAULT_DB_ALIAS
|
|
||||||
|
|
||||||
|
|
||||||
class Command(AppCommand):
|
|
||||||
help = "Prints the DROP INDEX SQL statements for the given model module name(s)."
|
|
||||||
|
|
||||||
output_transaction = True
|
|
||||||
|
|
||||||
def add_arguments(self, parser):
|
|
||||||
super(Command, self).add_arguments(parser)
|
|
||||||
parser.add_argument('--database', default=DEFAULT_DB_ALIAS,
|
|
||||||
help='Nominates a database to print the SQL for. Defaults to the '
|
|
||||||
'"default" database.')
|
|
||||||
|
|
||||||
def handle_app_config(self, app_config, **options):
|
|
||||||
if app_config.models_module is None:
|
|
||||||
return
|
|
||||||
connection = connections[options['database']]
|
|
||||||
statements = sql_destroy_indexes(app_config, self.style, connection)
|
|
||||||
return '\n'.join(statements)
|
|
|
@ -1,24 +0,0 @@
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
from django.core.management.base import AppCommand
|
|
||||||
from django.core.management.sql import sql_indexes
|
|
||||||
from django.db import connections, DEFAULT_DB_ALIAS
|
|
||||||
|
|
||||||
|
|
||||||
class Command(AppCommand):
|
|
||||||
help = "Prints the CREATE INDEX SQL statements for the given model module name(s)."
|
|
||||||
|
|
||||||
output_transaction = True
|
|
||||||
|
|
||||||
def add_arguments(self, parser):
|
|
||||||
super(Command, self).add_arguments(parser)
|
|
||||||
parser.add_argument('--database', default=DEFAULT_DB_ALIAS,
|
|
||||||
help='Nominates a database to print the SQL for. Defaults to the '
|
|
||||||
'"default" database.')
|
|
||||||
|
|
||||||
def handle_app_config(self, app_config, **options):
|
|
||||||
if app_config.models_module is None:
|
|
||||||
return
|
|
||||||
connection = connections[options['database']]
|
|
||||||
statements = sql_indexes(app_config, self.style, connection)
|
|
||||||
return '\n'.join(statements)
|
|
|
@ -1,120 +1,7 @@
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.apps import apps
|
from django.apps import apps
|
||||||
from django.core.management.base import CommandError
|
from django.db import models
|
||||||
from django.db import models, router
|
|
||||||
from django.utils.version import get_docs_version
|
|
||||||
|
|
||||||
|
|
||||||
def check_for_migrations(app_config, connection):
|
|
||||||
# Inner import, else tests imports it too early as it needs settings
|
|
||||||
from django.db.migrations.loader import MigrationLoader
|
|
||||||
loader = MigrationLoader(connection)
|
|
||||||
if app_config.label in loader.migrated_apps:
|
|
||||||
raise CommandError(
|
|
||||||
"App '%s' has migrations. Only the sqlmigrate and sqlflush commands "
|
|
||||||
"can be used when an app has migrations." % app_config.label
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def sql_create(app_config, style, connection):
|
|
||||||
"Returns a list of the CREATE TABLE SQL statements for the given app."
|
|
||||||
|
|
||||||
check_for_migrations(app_config, connection)
|
|
||||||
|
|
||||||
if connection.settings_dict['ENGINE'] == 'django.db.backends.dummy':
|
|
||||||
# This must be the "dummy" database backend, which means the user
|
|
||||||
# hasn't set ENGINE for the database.
|
|
||||||
raise CommandError(
|
|
||||||
"Django doesn't know which syntax to use for your SQL statements,\n"
|
|
||||||
"because you haven't properly specified the ENGINE setting for the database.\n"
|
|
||||||
"see: https://docs.djangoproject.com/en/%s/ref/settings/#databases" % get_docs_version()
|
|
||||||
)
|
|
||||||
|
|
||||||
# Get installed models, so we generate REFERENCES right.
|
|
||||||
# We trim models from the current app so that the sqlreset command does not
|
|
||||||
# generate invalid SQL (leaving models out of known_models is harmless, so
|
|
||||||
# we can be conservative).
|
|
||||||
app_models = list(app_config.get_models(include_auto_created=True))
|
|
||||||
final_output = []
|
|
||||||
tables = connection.introspection.table_names()
|
|
||||||
known_models = set(model for model in connection.introspection.installed_models(tables) if model not in app_models)
|
|
||||||
pending_references = {}
|
|
||||||
|
|
||||||
for model in router.get_migratable_models(app_config, connection.alias, include_auto_created=True):
|
|
||||||
output, references = connection.creation.sql_create_model(model, style, known_models)
|
|
||||||
final_output.extend(output)
|
|
||||||
for refto, refs in references.items():
|
|
||||||
pending_references.setdefault(refto, []).extend(refs)
|
|
||||||
if refto in known_models:
|
|
||||||
final_output.extend(connection.creation.sql_for_pending_references(refto, style, pending_references))
|
|
||||||
final_output.extend(connection.creation.sql_for_pending_references(model, style, pending_references))
|
|
||||||
# Keep track of the fact that we've created the table for this model.
|
|
||||||
known_models.add(model)
|
|
||||||
|
|
||||||
# Handle references to tables that are from other apps
|
|
||||||
# but don't exist physically.
|
|
||||||
not_installed_models = set(pending_references.keys())
|
|
||||||
if not_installed_models:
|
|
||||||
alter_sql = []
|
|
||||||
for model in not_installed_models:
|
|
||||||
alter_sql.extend('-- ' + sql for sql in
|
|
||||||
connection.creation.sql_for_pending_references(model, style, pending_references))
|
|
||||||
if alter_sql:
|
|
||||||
final_output.append('-- The following references should be added but depend on non-existent tables:')
|
|
||||||
final_output.extend(alter_sql)
|
|
||||||
|
|
||||||
return final_output
|
|
||||||
|
|
||||||
|
|
||||||
def sql_delete(app_config, style, connection, close_connection=True):
|
|
||||||
"Returns a list of the DROP TABLE SQL statements for the given app."
|
|
||||||
|
|
||||||
check_for_migrations(app_config, connection)
|
|
||||||
|
|
||||||
# This should work even if a connection isn't available
|
|
||||||
try:
|
|
||||||
cursor = connection.cursor()
|
|
||||||
except Exception:
|
|
||||||
cursor = None
|
|
||||||
|
|
||||||
try:
|
|
||||||
# Figure out which tables already exist
|
|
||||||
if cursor:
|
|
||||||
table_names = connection.introspection.table_names(cursor)
|
|
||||||
else:
|
|
||||||
table_names = []
|
|
||||||
|
|
||||||
output = []
|
|
||||||
|
|
||||||
# Output DROP TABLE statements for standard application tables.
|
|
||||||
to_delete = set()
|
|
||||||
|
|
||||||
references_to_delete = {}
|
|
||||||
app_models = router.get_migratable_models(app_config, connection.alias, include_auto_created=True)
|
|
||||||
for model in app_models:
|
|
||||||
if cursor and connection.introspection.table_name_converter(model._meta.db_table) in table_names:
|
|
||||||
# The table exists, so it needs to be dropped
|
|
||||||
opts = model._meta
|
|
||||||
for f in opts.local_fields:
|
|
||||||
if f.rel and f.rel.to not in to_delete:
|
|
||||||
references_to_delete.setdefault(f.rel.to, []).append((model, f))
|
|
||||||
|
|
||||||
to_delete.add(model)
|
|
||||||
|
|
||||||
for model in app_models:
|
|
||||||
if connection.introspection.table_name_converter(model._meta.db_table) in table_names:
|
|
||||||
output.extend(connection.creation.sql_destroy_model(model, references_to_delete, style))
|
|
||||||
finally:
|
|
||||||
# Close database connection explicitly, in case this output is being piped
|
|
||||||
# directly into a database client, to avoid locking issues.
|
|
||||||
if cursor and close_connection:
|
|
||||||
cursor.close()
|
|
||||||
connection.close()
|
|
||||||
|
|
||||||
if not output:
|
|
||||||
output.append('-- App creates no tables in the database. Nothing to do.')
|
|
||||||
return output[::-1] # Reverse it, to deal with table dependencies.
|
|
||||||
|
|
||||||
|
|
||||||
def sql_flush(style, connection, only_django=False, reset_sequences=True, allow_cascade=False):
|
def sql_flush(style, connection, only_django=False, reset_sequences=True, allow_cascade=False):
|
||||||
|
@ -133,39 +20,6 @@ def sql_flush(style, connection, only_django=False, reset_sequences=True, allow_
|
||||||
return statements
|
return statements
|
||||||
|
|
||||||
|
|
||||||
def sql_indexes(app_config, style, connection):
|
|
||||||
"Returns a list of the CREATE INDEX SQL statements for all models in the given app."
|
|
||||||
|
|
||||||
check_for_migrations(app_config, connection)
|
|
||||||
|
|
||||||
output = []
|
|
||||||
for model in router.get_migratable_models(app_config, connection.alias, include_auto_created=True):
|
|
||||||
output.extend(connection.creation.sql_indexes_for_model(model, style))
|
|
||||||
return output
|
|
||||||
|
|
||||||
|
|
||||||
def sql_destroy_indexes(app_config, style, connection):
|
|
||||||
"Returns a list of the DROP INDEX SQL statements for all models in the given app."
|
|
||||||
|
|
||||||
check_for_migrations(app_config, connection)
|
|
||||||
|
|
||||||
output = []
|
|
||||||
for model in router.get_migratable_models(app_config, connection.alias, include_auto_created=True):
|
|
||||||
output.extend(connection.creation.sql_destroy_indexes_for_model(model, style))
|
|
||||||
return output
|
|
||||||
|
|
||||||
|
|
||||||
def sql_all(app_config, style, connection):
|
|
||||||
|
|
||||||
check_for_migrations(app_config, connection)
|
|
||||||
|
|
||||||
"Returns a list of CREATE TABLE SQL, initial-data inserts, and CREATE INDEX SQL for the given module."
|
|
||||||
return (
|
|
||||||
sql_create(app_config, style, connection) +
|
|
||||||
sql_indexes(app_config, style, connection)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def emit_pre_migrate_signal(verbosity, interactive, db):
|
def emit_pre_migrate_signal(verbosity, interactive, db):
|
||||||
# Emit the pre_migrate signal for every application.
|
# Emit the pre_migrate signal for every application.
|
||||||
for app_config in apps.get_app_configs():
|
for app_config in apps.get_app_configs():
|
||||||
|
|
|
@ -366,6 +366,7 @@ class BaseDatabaseCreation(object):
|
||||||
verbosity=max(verbosity - 1, 0),
|
verbosity=max(verbosity - 1, 0),
|
||||||
interactive=False,
|
interactive=False,
|
||||||
database=self.connection.alias,
|
database=self.connection.alias,
|
||||||
|
run_syncdb=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
# We then serialize the current state of the database into a string
|
# We then serialize the current state of the database into a string
|
||||||
|
|
|
@ -537,16 +537,13 @@ Now, run :djadmin:`migrate` again to create those model tables in your database:
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
$ python manage.py migrate
|
$ python manage.py migrate
|
||||||
|
|
||||||
Operations to perform:
|
Operations to perform:
|
||||||
Synchronize unmigrated apps: sessions, admin, messages, auth, staticfiles, contenttypes
|
Apply all migrations: admin, contenttypes, polls, auth, sessions
|
||||||
Apply all migrations: polls
|
|
||||||
Synchronizing apps without migrations:
|
|
||||||
Creating tables...
|
|
||||||
Installing indexes...
|
|
||||||
Running migrations:
|
Running migrations:
|
||||||
|
Rendering model states... DONE
|
||||||
|
...
|
||||||
Applying polls.0001_initial... OK
|
Applying polls.0001_initial... OK
|
||||||
|
...
|
||||||
|
|
||||||
The :djadmin:`migrate` command takes all the migrations that haven't been
|
The :djadmin:`migrate` command takes all the migrations that haven't been
|
||||||
applied (Django tracks which ones are applied using a special table in your
|
applied (Django tracks which ones are applied using a special table in your
|
||||||
|
|
|
@ -74,22 +74,9 @@ The
|
||||||
option forces the use of the standard Python interpreter even when IPython is
|
option forces the use of the standard Python interpreter even when IPython is
|
||||||
installed.
|
installed.
|
||||||
.TP
|
.TP
|
||||||
.BI "sql [" "app_label ..." "]"
|
|
||||||
Prints the CREATE TABLE SQL statements for the given app name(s).
|
|
||||||
.TP
|
|
||||||
.BI "sqlall [" "app_label ..." "]"
|
|
||||||
Prints the CREATE TABLE, initial\-data and CREATE INDEX SQL statements for the
|
|
||||||
given model module name(s).
|
|
||||||
.TP
|
|
||||||
.BI "sqlclear [" "app_label ..." "]"
|
|
||||||
Prints the DROP TABLE SQL statements for the given app name(s).
|
|
||||||
.TP
|
|
||||||
.BI "sqlflush [" "app_label ..." "]"
|
.BI "sqlflush [" "app_label ..." "]"
|
||||||
Prints the SQL statements that would be executed for the "flush" command.
|
Prints the SQL statements that would be executed for the "flush" command.
|
||||||
.TP
|
.TP
|
||||||
.BI "sqlindexes [" "app_label ..." "]"
|
|
||||||
Prints the CREATE INDEX SQL statements for the given model module name(s).
|
|
||||||
.TP
|
|
||||||
.BI "sqlsequencereset [" "app_label ..." "]"
|
.BI "sqlsequencereset [" "app_label ..." "]"
|
||||||
Prints the SQL statements for resetting PostgreSQL sequences for the
|
Prints the SQL statements for resetting PostgreSQL sequences for the
|
||||||
given app name(s).
|
given app name(s).
|
||||||
|
@ -103,8 +90,7 @@ Creates a Django project directory structure for the given project name
|
||||||
in the current directory or the optional destination.
|
in the current directory or the optional destination.
|
||||||
.TP
|
.TP
|
||||||
.BI migrate
|
.BI migrate
|
||||||
Runs migrations for apps containing migrations, and just creates missing tables
|
Runs migrations for all apps.
|
||||||
for apps without migrations.
|
|
||||||
.TP
|
.TP
|
||||||
.BI "test [" "\-\-verbosity" "] [" "\-\-failfast" "] [" "app_label ..." "]"
|
.BI "test [" "\-\-verbosity" "] [" "\-\-failfast" "] [" "app_label ..." "]"
|
||||||
Runs the test suite for the specified applications, or the entire project if
|
Runs the test suite for the specified applications, or the entire project if
|
||||||
|
|
|
@ -963,53 +963,6 @@ beyond those apps. Same as ``--list``, applied migrations are marked by an
|
||||||
``[X]``. For a verbosity of 2 and above, all dependencies of a migration will
|
``[X]``. For a verbosity of 2 and above, all dependencies of a migration will
|
||||||
also be shown.
|
also be shown.
|
||||||
|
|
||||||
sql <app_label app_label ...>
|
|
||||||
-----------------------------
|
|
||||||
|
|
||||||
.. django-admin:: sql
|
|
||||||
|
|
||||||
Prints the CREATE TABLE SQL statements for the given app name(s).
|
|
||||||
|
|
||||||
The :djadminopt:`--database` option can be used to specify the database for
|
|
||||||
which to print the SQL.
|
|
||||||
|
|
||||||
sqlall <app_label app_label ...>
|
|
||||||
--------------------------------
|
|
||||||
|
|
||||||
.. django-admin:: sqlall
|
|
||||||
|
|
||||||
Prints the CREATE TABLE and initial-data SQL statements for the given app name(s).
|
|
||||||
|
|
||||||
The :djadminopt:`--database` option can be used to specify the database for
|
|
||||||
which to print the SQL.
|
|
||||||
|
|
||||||
.. versionchanged:: 1.7
|
|
||||||
|
|
||||||
The ``sql*`` management commands now respect the ``allow_migrate()`` method
|
|
||||||
of :setting:`DATABASE_ROUTERS`. If you have models synced to non-default
|
|
||||||
databases, use the :djadminopt:`--database` flag to get SQL for those
|
|
||||||
models (previously they would always be included in the output).
|
|
||||||
|
|
||||||
sqlclear <app_label app_label ...>
|
|
||||||
----------------------------------
|
|
||||||
|
|
||||||
.. django-admin:: sqlclear
|
|
||||||
|
|
||||||
Prints the DROP TABLE SQL statements for the given app name(s).
|
|
||||||
|
|
||||||
The :djadminopt:`--database` option can be used to specify the database for
|
|
||||||
which to print the SQL.
|
|
||||||
|
|
||||||
sqldropindexes <app_label app_label ...>
|
|
||||||
----------------------------------------
|
|
||||||
|
|
||||||
.. django-admin:: sqldropindexes
|
|
||||||
|
|
||||||
Prints the DROP INDEX SQL statements for the given app name(s).
|
|
||||||
|
|
||||||
The :djadminopt:`--database` option can be used to specify the database for
|
|
||||||
which to print the SQL.
|
|
||||||
|
|
||||||
sqlflush
|
sqlflush
|
||||||
--------
|
--------
|
||||||
|
|
||||||
|
@ -1021,16 +974,6 @@ command.
|
||||||
The :djadminopt:`--database` option can be used to specify the database for
|
The :djadminopt:`--database` option can be used to specify the database for
|
||||||
which to print the SQL.
|
which to print the SQL.
|
||||||
|
|
||||||
sqlindexes <app_label app_label ...>
|
|
||||||
------------------------------------
|
|
||||||
|
|
||||||
.. django-admin:: sqlindexes
|
|
||||||
|
|
||||||
Prints the CREATE INDEX SQL statements for the given app name(s).
|
|
||||||
|
|
||||||
The :djadminopt:`--database` option can be used to specify the database for
|
|
||||||
which to print the SQL.
|
|
||||||
|
|
||||||
sqlmigrate <app_label> <migrationname>
|
sqlmigrate <app_label> <migrationname>
|
||||||
--------------------------------------
|
--------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -183,8 +183,7 @@ scenes.
|
||||||
|
|
||||||
.. attribute:: Field.db_index
|
.. attribute:: Field.db_index
|
||||||
|
|
||||||
If ``True``, :djadmin:`django-admin sqlindexes <sqlindexes>` will output a
|
If ``True``, a database index will be created for this field.
|
||||||
``CREATE INDEX`` statement for this field.
|
|
||||||
|
|
||||||
``db_tablespace``
|
``db_tablespace``
|
||||||
-----------------
|
-----------------
|
||||||
|
@ -1120,12 +1119,6 @@ avoid the overhead of an index if you are creating a foreign key for
|
||||||
consistency rather than joins, or if you will be creating an alternative index
|
consistency rather than joins, or if you will be creating an alternative index
|
||||||
like a partial or multiple column index.
|
like a partial or multiple column index.
|
||||||
|
|
||||||
.. warning::
|
|
||||||
|
|
||||||
It is not recommended to have a ``ForeignKey`` from an app without migrations
|
|
||||||
to an app with migrations. See the :ref:`dependencies documentation
|
|
||||||
<unmigrated-dependencies>` for more details.
|
|
||||||
|
|
||||||
Database Representation
|
Database Representation
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
@ -1335,12 +1328,6 @@ which the model is related, which works exactly the same as it does for
|
||||||
Related objects can be added, removed, or created with the field's
|
Related objects can be added, removed, or created with the field's
|
||||||
:class:`~django.db.models.fields.related.RelatedManager`.
|
:class:`~django.db.models.fields.related.RelatedManager`.
|
||||||
|
|
||||||
.. warning::
|
|
||||||
|
|
||||||
It is not recommended to have a ``ManyToManyField`` from an app without migrations
|
|
||||||
to an app with migrations. See the :ref:`dependencies documentation
|
|
||||||
<unmigrated-dependencies>` for more details.
|
|
||||||
|
|
||||||
Database Representation
|
Database Representation
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
|
@ -2397,9 +2397,9 @@ Default: ``[]``
|
||||||
|
|
||||||
In order to restore the database state between tests for
|
In order to restore the database state between tests for
|
||||||
``TransactionTestCase``\s and database backends without transactions, Django
|
``TransactionTestCase``\s and database backends without transactions, Django
|
||||||
will :ref:`serialize the contents of all apps with migrations
|
will :ref:`serialize the contents of all apps <test-case-serialized-rollback>`
|
||||||
<test-case-serialized-rollback>` when it starts the test run so it can then
|
when it starts the test run so it can then reload from that copy before tests
|
||||||
reload from that copy before tests that need it.
|
that need it.
|
||||||
|
|
||||||
This slows down the startup time of the test runner; if you have apps that
|
This slows down the startup time of the test runner; if you have apps that
|
||||||
you know don't need this feature, you can add their full names in here (e.g.
|
you know don't need this feature, you can add their full names in here (e.g.
|
||||||
|
|
|
@ -432,8 +432,7 @@ If you have an existing project that is using the database session
|
||||||
backend, you don't have to do anything to accommodate this change.
|
backend, you don't have to do anything to accommodate this change.
|
||||||
However, you may get a significant performance boost if you manually
|
However, you may get a significant performance boost if you manually
|
||||||
add the new index to the session table. The SQL that will add the
|
add the new index to the session table. The SQL that will add the
|
||||||
index can be found by running the :djadmin:`sqlindexes` admin
|
index can be found by running the ``sqlindexes`` admin command::
|
||||||
command::
|
|
||||||
|
|
||||||
python manage.py sqlindexes sessions
|
python manage.py sqlindexes sessions
|
||||||
|
|
||||||
|
|
|
@ -74,9 +74,8 @@ but a few of the key features are:
|
||||||
<test-case-serialized-rollback>`.
|
<test-case-serialized-rollback>`.
|
||||||
|
|
||||||
* It is not advised to have apps without migrations depend on (have a
|
* It is not advised to have apps without migrations depend on (have a
|
||||||
:ref:`ForeignKey <ref-foreignkey>` or :ref:`ManyToManyField <ref-manytomany>` to) apps with migrations. Read the
|
:ref:`ForeignKey <ref-foreignkey>` or :ref:`ManyToManyField <ref-manytomany>`
|
||||||
:ref:`dependencies documentation <unmigrated-dependencies>` for more.
|
to) apps with migrations.
|
||||||
|
|
||||||
|
|
||||||
* If you are upgrading from South, see our :ref:`upgrading-from-south`
|
* If you are upgrading from South, see our :ref:`upgrading-from-south`
|
||||||
documentation, and third-party app authors should read the
|
documentation, and third-party app authors should read the
|
||||||
|
|
|
@ -582,12 +582,7 @@ spam
|
||||||
spammers
|
spammers
|
||||||
spatialite
|
spatialite
|
||||||
Springmeyer
|
Springmeyer
|
||||||
sql
|
|
||||||
sqlall
|
|
||||||
sqlclear
|
|
||||||
sqldropindexes
|
|
||||||
sqlflush
|
sqlflush
|
||||||
sqlindexes
|
|
||||||
sqlmigrate
|
sqlmigrate
|
||||||
sqlsequencereset
|
sqlsequencereset
|
||||||
squashmigrations
|
squashmigrations
|
||||||
|
|
|
@ -136,12 +136,9 @@ database to make sure they work as expected::
|
||||||
|
|
||||||
$ python manage.py migrate
|
$ python manage.py migrate
|
||||||
Operations to perform:
|
Operations to perform:
|
||||||
Synchronize unmigrated apps: sessions, admin, messages, auth, staticfiles, contenttypes
|
|
||||||
Apply all migrations: books
|
Apply all migrations: books
|
||||||
Synchronizing apps without migrations:
|
|
||||||
Creating tables...
|
|
||||||
Installing indexes...
|
|
||||||
Running migrations:
|
Running migrations:
|
||||||
|
Rendering model states... DONE
|
||||||
Applying books.0003_auto... OK
|
Applying books.0003_auto... OK
|
||||||
|
|
||||||
The command runs in two stages; first, it synchronizes unmigrated apps, and
|
The command runs in two stages; first, it synchronizes unmigrated apps, and
|
||||||
|
@ -195,26 +192,6 @@ restrict to a single app. Restricting to a single app (either in
|
||||||
a guarantee; any other apps that need to be used to get dependencies correct
|
a guarantee; any other apps that need to be used to get dependencies correct
|
||||||
will be.
|
will be.
|
||||||
|
|
||||||
.. _unmigrated-dependencies:
|
|
||||||
|
|
||||||
Be aware, however, that unmigrated apps cannot depend on migrated apps, by the
|
|
||||||
very nature of not having migrations. This means that it is not generally
|
|
||||||
possible to have an unmigrated app have a ``ForeignKey`` or ``ManyToManyField``
|
|
||||||
to a migrated app; some cases may work, but it will eventually fail.
|
|
||||||
|
|
||||||
.. warning::
|
|
||||||
|
|
||||||
Even if things appear to work with unmigrated apps depending on migrated
|
|
||||||
apps, Django may not generate all the necessary foreign key constraints!
|
|
||||||
|
|
||||||
This is particularly apparent if you use swappable models (e.g.
|
|
||||||
``AUTH_USER_MODEL``), as every app that uses swappable models will need
|
|
||||||
to have migrations if you're unlucky. As time goes on, more and more
|
|
||||||
third-party apps will get migrations, but in the meantime you can either
|
|
||||||
give them migrations yourself (using :setting:`MIGRATION_MODULES` to
|
|
||||||
store those modules outside of the app's own module if you wish), or
|
|
||||||
keep the app with your user model unmigrated.
|
|
||||||
|
|
||||||
.. _migration-files:
|
.. _migration-files:
|
||||||
|
|
||||||
Migration files
|
Migration files
|
||||||
|
|
|
@ -670,12 +670,12 @@ to test the effects of commit and rollback:
|
||||||
|
|
||||||
.. warning::
|
.. warning::
|
||||||
|
|
||||||
``TestCase`` running on a database that does not support rollback (e.g. MySQL with the
|
``TestCase`` running on a database that does not support rollback (e.g. MySQL
|
||||||
MyISAM storage engine), and all instances of ``TransactionTestCase``, will
|
with the MyISAM storage engine), and all instances of ``TransactionTestCase``,
|
||||||
roll back at the end of the test by deleting all data from the test database
|
will roll back at the end of the test by deleting all data from the test
|
||||||
and reloading initial data for apps without migrations.
|
database.
|
||||||
|
|
||||||
Apps with migrations :ref:`will not see their data reloaded <test-case-serialized-rollback>`;
|
Apps :ref:`will not see their data reloaded <test-case-serialized-rollback>`;
|
||||||
if you need this functionality (for example, third-party apps should enable
|
if you need this functionality (for example, third-party apps should enable
|
||||||
this) you can set ``serialized_rollback = True`` inside the
|
this) you can set ``serialized_rollback = True`` inside the
|
||||||
``TestCase`` body.
|
``TestCase`` body.
|
||||||
|
|
|
@ -319,13 +319,6 @@ class DjangoAdminFullPathDefaultSettings(AdminScriptTestCase):
|
||||||
self.assertNoOutput(err)
|
self.assertNoOutput(err)
|
||||||
self.assertOutput(out, SYSTEM_CHECK_MSG)
|
self.assertOutput(out, SYSTEM_CHECK_MSG)
|
||||||
|
|
||||||
def test_sqlclear_builtin_with_settings(self):
|
|
||||||
"fulldefault: django-admin builtin commands succeed if a setting file is provided"
|
|
||||||
args = ['sqlclear', '--settings=test_project.settings', 'complex_app']
|
|
||||||
out, err = self.run_django_admin(args)
|
|
||||||
self.assertNoOutput(err)
|
|
||||||
self.assertOutput(out, '-- App creates no tables in the database. Nothing to do.')
|
|
||||||
|
|
||||||
def test_builtin_with_environment(self):
|
def test_builtin_with_environment(self):
|
||||||
"fulldefault: django-admin builtin commands succeed if the environment contains settings"
|
"fulldefault: django-admin builtin commands succeed if the environment contains settings"
|
||||||
args = ['check', 'admin_scripts']
|
args = ['check', 'admin_scripts']
|
||||||
|
|
|
@ -78,7 +78,7 @@ class BashCompletionTests(unittest.TestCase):
|
||||||
"Subcommands can be autocompleted"
|
"Subcommands can be autocompleted"
|
||||||
self._user_input('django-admin sql')
|
self._user_input('django-admin sql')
|
||||||
output = self._run_autocomplete()
|
output = self._run_autocomplete()
|
||||||
self.assertEqual(output, ['sql sqlall sqlclear sqldropindexes sqlflush sqlindexes sqlmigrate sqlsequencereset'])
|
self.assertEqual(output, ['sqlflush sqlmigrate sqlsequencereset'])
|
||||||
|
|
||||||
def test_completed_subcommand(self):
|
def test_completed_subcommand(self):
|
||||||
"Show option flags in case a subcommand is completed"
|
"Show option flags in case a subcommand is completed"
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
from django.db import models
|
|
||||||
|
|
||||||
|
|
||||||
class Comment(models.Model):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class Book(models.Model):
|
|
||||||
title = models.CharField(max_length=100, db_index=True)
|
|
||||||
comments = models.ManyToManyField(Comment)
|
|
||||||
counter = models.PositiveIntegerField()
|
|
|
@ -1,111 +0,0 @@
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
import re
|
|
||||||
import unittest
|
|
||||||
|
|
||||||
from django.apps import apps
|
|
||||||
from django.core.management.color import no_style
|
|
||||||
from django.core.management.sql import (sql_create, sql_delete, sql_indexes,
|
|
||||||
sql_destroy_indexes, sql_all)
|
|
||||||
from django.db import connections, DEFAULT_DB_ALIAS
|
|
||||||
from django.test import TestCase, ignore_warnings, override_settings
|
|
||||||
from django.utils import six
|
|
||||||
from django.utils.deprecation import RemovedInDjango20Warning
|
|
||||||
|
|
||||||
# See also initial_sql_regress for 'custom_sql_for_model' tests
|
|
||||||
|
|
||||||
|
|
||||||
class SQLCommandsTestCase(TestCase):
|
|
||||||
"""Tests for several functions in django/core/management/sql.py"""
|
|
||||||
def count_ddl(self, output, cmd):
|
|
||||||
return len([o for o in output if o.startswith(cmd)])
|
|
||||||
|
|
||||||
def test_sql_create(self):
|
|
||||||
app_config = apps.get_app_config('commands_sql')
|
|
||||||
output = sql_create(app_config, no_style(), connections[DEFAULT_DB_ALIAS])
|
|
||||||
|
|
||||||
tables = set()
|
|
||||||
create_table_re = re.compile(r'^create table .(?P<table>[\w_]+).*', re.IGNORECASE)
|
|
||||||
reference_re = re.compile(r'.* references .(?P<table>[\w_]+).*', re.IGNORECASE)
|
|
||||||
for statement in output:
|
|
||||||
create_table = create_table_re.match(statement)
|
|
||||||
if create_table:
|
|
||||||
# Lower since Oracle's table names are upper cased.
|
|
||||||
tables.add(create_table.group('table').lower())
|
|
||||||
continue
|
|
||||||
reference = reference_re.match(statement)
|
|
||||||
if reference:
|
|
||||||
# Lower since Oracle's table names are upper cased.
|
|
||||||
table = reference.group('table').lower()
|
|
||||||
self.assertIn(
|
|
||||||
table, tables, "The table %s is referenced before its creation." % table
|
|
||||||
)
|
|
||||||
|
|
||||||
self.assertEqual(tables, {
|
|
||||||
'commands_sql_comment', 'commands_sql_book', 'commands_sql_book_comments'
|
|
||||||
})
|
|
||||||
|
|
||||||
@unittest.skipUnless('PositiveIntegerField' in connections[DEFAULT_DB_ALIAS].data_type_check_constraints, 'Backend does not have checks.')
|
|
||||||
def test_sql_create_check(self):
|
|
||||||
"""Regression test for #23416 -- Check that db_params['check'] is respected."""
|
|
||||||
app_config = apps.get_app_config('commands_sql')
|
|
||||||
output = sql_create(app_config, no_style(), connections[DEFAULT_DB_ALIAS])
|
|
||||||
success = False
|
|
||||||
for statement in output:
|
|
||||||
if 'CHECK' in statement:
|
|
||||||
success = True
|
|
||||||
if not success:
|
|
||||||
self.fail("'CHECK' not found in output %s" % output)
|
|
||||||
|
|
||||||
def test_sql_delete(self):
|
|
||||||
app_config = apps.get_app_config('commands_sql')
|
|
||||||
output = sql_delete(app_config, no_style(), connections[DEFAULT_DB_ALIAS], close_connection=False)
|
|
||||||
drop_tables = [o for o in output if o.startswith('DROP TABLE')]
|
|
||||||
self.assertEqual(len(drop_tables), 3)
|
|
||||||
# Lower so that Oracle's upper case tbl names wont break
|
|
||||||
sql = drop_tables[-1].lower()
|
|
||||||
six.assertRegex(self, sql, r'^drop table .commands_sql_comment.*')
|
|
||||||
|
|
||||||
@ignore_warnings(category=RemovedInDjango20Warning)
|
|
||||||
def test_sql_indexes(self):
|
|
||||||
app_config = apps.get_app_config('commands_sql')
|
|
||||||
output = sql_indexes(app_config, no_style(), connections[DEFAULT_DB_ALIAS])
|
|
||||||
# Number of indexes is backend-dependent
|
|
||||||
self.assertTrue(1 <= self.count_ddl(output, 'CREATE INDEX') <= 4)
|
|
||||||
|
|
||||||
def test_sql_destroy_indexes(self):
|
|
||||||
app_config = apps.get_app_config('commands_sql')
|
|
||||||
output = sql_destroy_indexes(app_config, no_style(), connections[DEFAULT_DB_ALIAS])
|
|
||||||
# Number of indexes is backend-dependent
|
|
||||||
self.assertTrue(1 <= self.count_ddl(output, 'DROP INDEX') <= 4)
|
|
||||||
|
|
||||||
@ignore_warnings(category=RemovedInDjango20Warning)
|
|
||||||
def test_sql_all(self):
|
|
||||||
app_config = apps.get_app_config('commands_sql')
|
|
||||||
output = sql_all(app_config, no_style(), connections[DEFAULT_DB_ALIAS])
|
|
||||||
|
|
||||||
self.assertEqual(self.count_ddl(output, 'CREATE TABLE'), 3)
|
|
||||||
# Number of indexes is backend-dependent
|
|
||||||
self.assertTrue(1 <= self.count_ddl(output, 'CREATE INDEX') <= 4)
|
|
||||||
|
|
||||||
|
|
||||||
class TestRouter(object):
|
|
||||||
def allow_migrate(self, db, model):
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
@override_settings(DATABASE_ROUTERS=[TestRouter()])
|
|
||||||
class SQLCommandsRouterTestCase(TestCase):
|
|
||||||
|
|
||||||
def test_router_honored(self):
|
|
||||||
app_config = apps.get_app_config('commands_sql')
|
|
||||||
for sql_command in (sql_all, sql_create, sql_delete, sql_indexes, sql_destroy_indexes):
|
|
||||||
if sql_command is sql_delete:
|
|
||||||
output = sql_command(app_config, no_style(), connections[DEFAULT_DB_ALIAS], close_connection=False)
|
|
||||||
# "App creates no tables in the database. Nothing to do."
|
|
||||||
expected_output = 1
|
|
||||||
else:
|
|
||||||
output = sql_command(app_config, no_style(), connections[DEFAULT_DB_ALIAS])
|
|
||||||
expected_output = 0
|
|
||||||
self.assertEqual(len(output), expected_output,
|
|
||||||
"%s command is not honoring routers" % sql_command.__name__)
|
|
|
@ -1,33 +0,0 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
from django.db import models, migrations
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.CreateModel(
|
|
||||||
name='Comment',
|
|
||||||
fields=[
|
|
||||||
('id', models.AutoField(verbose_name='ID', primary_key=True, serialize=False, auto_created=True)),
|
|
||||||
],
|
|
||||||
options={
|
|
||||||
},
|
|
||||||
bases=(models.Model,),
|
|
||||||
),
|
|
||||||
migrations.CreateModel(
|
|
||||||
name='Book',
|
|
||||||
fields=[
|
|
||||||
('id', models.AutoField(verbose_name='ID', primary_key=True, serialize=False, auto_created=True)),
|
|
||||||
('title', models.CharField(db_index=True, max_length=100)),
|
|
||||||
('comments', models.ManyToManyField(to='commands_sql_migrations.Comment')),
|
|
||||||
],
|
|
||||||
options={
|
|
||||||
},
|
|
||||||
bases=(models.Model,),
|
|
||||||
),
|
|
||||||
]
|
|
|
@ -1,10 +0,0 @@
|
||||||
from django.db import models
|
|
||||||
|
|
||||||
|
|
||||||
class Comment(models.Model):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class Book(models.Model):
|
|
||||||
title = models.CharField(max_length=100, db_index=True)
|
|
||||||
comments = models.ManyToManyField(Comment)
|
|
|
@ -1,39 +0,0 @@
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
from django.apps import apps
|
|
||||||
from django.core.management import CommandError
|
|
||||||
from django.core.management.color import no_style
|
|
||||||
from django.core.management.sql import (sql_create, sql_delete, sql_indexes,
|
|
||||||
sql_destroy_indexes, sql_all)
|
|
||||||
from django.db import connections, DEFAULT_DB_ALIAS
|
|
||||||
from django.test import TestCase
|
|
||||||
|
|
||||||
|
|
||||||
class SQLCommandsMigrationsTestCase(TestCase):
|
|
||||||
"""Tests that apps with migrations can not use sql commands."""
|
|
||||||
|
|
||||||
def test_sql_create(self):
|
|
||||||
app_config = apps.get_app_config('commands_sql_migrations')
|
|
||||||
with self.assertRaises(CommandError):
|
|
||||||
sql_create(app_config, no_style(), connections[DEFAULT_DB_ALIAS])
|
|
||||||
|
|
||||||
def test_sql_delete(self):
|
|
||||||
app_config = apps.get_app_config('commands_sql_migrations')
|
|
||||||
with self.assertRaises(CommandError):
|
|
||||||
sql_delete(app_config, no_style(), connections[DEFAULT_DB_ALIAS], close_connection=False)
|
|
||||||
|
|
||||||
def test_sql_indexes(self):
|
|
||||||
app_config = apps.get_app_config('commands_sql_migrations')
|
|
||||||
with self.assertRaises(CommandError):
|
|
||||||
sql_indexes(app_config, no_style(), connections[DEFAULT_DB_ALIAS])
|
|
||||||
|
|
||||||
def test_sql_destroy_indexes(self):
|
|
||||||
app_config = apps.get_app_config('commands_sql_migrations')
|
|
||||||
with self.assertRaises(CommandError):
|
|
||||||
sql_destroy_indexes(app_config, no_style(),
|
|
||||||
connections[DEFAULT_DB_ALIAS])
|
|
||||||
|
|
||||||
def test_sql_all(self):
|
|
||||||
app_config = apps.get_app_config('commands_sql_migrations')
|
|
||||||
with self.assertRaises(CommandError):
|
|
||||||
sql_all(app_config, no_style(), connections[DEFAULT_DB_ALIAS])
|
|
|
@ -404,7 +404,7 @@ class InheritanceSameModelNameTests(TransactionTestCase):
|
||||||
def test_inheritance_with_same_model_name(self):
|
def test_inheritance_with_same_model_name(self):
|
||||||
with self.modify_settings(
|
with self.modify_settings(
|
||||||
INSTALLED_APPS={'append': ['model_inheritance.same_model_name']}):
|
INSTALLED_APPS={'append': ['model_inheritance.same_model_name']}):
|
||||||
call_command('migrate', verbosity=0)
|
call_command('migrate', verbosity=0, run_syncdb=True)
|
||||||
from .same_model_name.models import Copy
|
from .same_model_name.models import Copy
|
||||||
copy = self.title.attached_same_model_name_copy_set.create(
|
copy = self.title.attached_same_model_name_copy_set.create(
|
||||||
content='The Web framework for perfectionists with deadlines.',
|
content='The Web framework for perfectionists with deadlines.',
|
||||||
|
|
|
@ -22,7 +22,7 @@ class ProxyModelInheritanceTests(TransactionTestCase):
|
||||||
def test_table_exists(self):
|
def test_table_exists(self):
|
||||||
with extend_sys_path(os.path.dirname(os.path.abspath(upath(__file__)))):
|
with extend_sys_path(os.path.dirname(os.path.abspath(upath(__file__)))):
|
||||||
with self.modify_settings(INSTALLED_APPS={'append': ['app1', 'app2']}):
|
with self.modify_settings(INSTALLED_APPS={'append': ['app1', 'app2']}):
|
||||||
call_command('migrate', verbosity=0)
|
call_command('migrate', verbosity=0, run_syncdb=True)
|
||||||
from app1.models import ProxyModel
|
from app1.models import ProxyModel
|
||||||
from app2.models import NiceModel
|
from app2.models import NiceModel
|
||||||
self.assertEqual(NiceModel.objects.all().count(), 0)
|
self.assertEqual(NiceModel.objects.all().count(), 0)
|
||||||
|
|
Loading…
Reference in New Issue