mirror of https://github.com/django/django.git
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