Fixed #25884 -- Fixed migrate --run-syncdb when specifying an app label.

This commit is contained in:
Sarah Guermond 2018-07-15 20:32:47 -07:00 committed by Tim Graham
parent e819554018
commit cd40306854
4 changed files with 51 additions and 6 deletions

View File

@ -104,6 +104,7 @@ 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 = options['run_syncdb']
target_app_labels_only = True target_app_labels_only = True
if options['app_label']: if options['app_label']:
# Validate app_label. # Validate app_label.
@ -112,7 +113,10 @@ class Command(BaseCommand):
apps.get_app_config(app_label) apps.get_app_config(app_label)
except LookupError as err: except LookupError as err:
raise CommandError(str(err)) raise CommandError(str(err))
if app_label not in executor.loader.migrated_apps: if run_syncdb:
if app_label in executor.loader.migrated_apps:
raise CommandError("Can't use run_syncdb with app '%s' as it has migrations." % app_label)
elif app_label not in executor.loader.migrated_apps:
raise CommandError("App '%s' does not have migrations." % app_label) raise CommandError("App '%s' does not have migrations." % app_label)
if options['app_label'] and options['migration_name']: if options['app_label'] and options['migration_name']:
@ -152,11 +156,17 @@ class Command(BaseCommand):
self.stdout.write(' ' + message, style) self.stdout.write(' ' + message, style)
return return
# At this point, ignore run_syncdb if there aren't any apps to sync.
run_syncdb = options['run_syncdb'] and executor.loader.unmigrated_apps run_syncdb = options['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: if run_syncdb:
if options['app_label']:
self.stdout.write(
self.style.MIGRATE_LABEL(" Synchronize unmigrated app: %s" % app_label)
)
else:
self.stdout.write( self.stdout.write(
self.style.MIGRATE_LABEL(" Synchronize unmigrated apps: ") + self.style.MIGRATE_LABEL(" Synchronize unmigrated apps: ") +
(", ".join(sorted(executor.loader.unmigrated_apps))) (", ".join(sorted(executor.loader.unmigrated_apps)))
@ -187,6 +197,9 @@ class Command(BaseCommand):
if run_syncdb: 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:"))
if options['app_label']:
self.sync_apps(connection, [app_label])
else:
self.sync_apps(connection, executor.loader.unmigrated_apps) self.sync_apps(connection, executor.loader.unmigrated_apps)
# Migrate! # Migrate!

View File

@ -0,0 +1,9 @@
from django.db import models
class UnmigratedModel(models.Model):
"""
A model that is in a migration-less app (which this app is
if its migrations directory has not been repointed)
"""
pass

View File

@ -663,6 +663,29 @@ class MigrateTests(MigrationTestBase):
table_name = truncate_name('unmigrated_app_syncdb_classroom', connection.ops.max_name_length()) table_name = truncate_name('unmigrated_app_syncdb_classroom', connection.ops.max_name_length())
self.assertIn('Creating table %s' % table_name, stdout) self.assertIn('Creating table %s' % table_name, stdout)
@override_settings(MIGRATION_MODULES={'migrations': 'migrations.test_migrations'})
def test_migrate_syncdb_app_with_migrations(self):
msg = "Can't use run_syncdb with app 'migrations' as it has migrations."
with self.assertRaisesMessage(CommandError, msg):
call_command('migrate', 'migrations', run_syncdb=True, verbosity=0)
@override_settings(INSTALLED_APPS=[
'migrations.migrations_test_apps.unmigrated_app_syncdb',
'migrations.migrations_test_apps.unmigrated_app_simple',
])
def test_migrate_syncdb_app_label(self):
"""
Running migrate --run-syncdb with an app_label only creates tables for
the specified app.
"""
stdout = io.StringIO()
with mock.patch.object(BaseDatabaseSchemaEditor, 'execute') as execute:
call_command('migrate', 'unmigrated_app_syncdb', run_syncdb=True, stdout=stdout)
create_table_count = len([call for call in execute.mock_calls if 'CREATE TABLE' in str(call)])
self.assertEqual(create_table_count, 2)
self.assertGreater(len(execute.mock_calls), 2)
self.assertIn('Synchronize unmigrated app: unmigrated_app_syncdb', stdout.getvalue())
@override_settings(MIGRATION_MODULES={"migrations": "migrations.test_migrations_squashed"}) @override_settings(MIGRATION_MODULES={"migrations": "migrations.test_migrations_squashed"})
def test_migrate_record_replaced(self): def test_migrate_record_replaced(self):
""" """