Refs #29198 -- Fixed migrate --plan crash if RunSQL uses a list or tuple.

Also fixed test failures if sqlparse isn't installed.
This commit is contained in:
Tim Graham 2018-09-19 15:27:40 -04:00
parent c99d379f53
commit 495abe0095
4 changed files with 28 additions and 20 deletions

View File

@ -344,7 +344,7 @@ class Command(BaseCommand):
action = 'IRREVERSIBLE' action = 'IRREVERSIBLE'
is_error = True is_error = True
else: else:
action = action.replace('\n', '') action = str(action).replace('\n', '')
is_error = False is_error = False
if action: if action:
action = ' -> ' + action action = ' -> ' + action

View File

@ -20,6 +20,11 @@ from .models import UnicodeModel, UnserializableModel
from .routers import TestRouter from .routers import TestRouter
from .test_base import MigrationTestBase from .test_base import MigrationTestBase
try:
import sqlparse
except ImportError:
sqlparse = None
class MigrateTests(MigrationTestBase): class MigrateTests(MigrationTestBase):
""" """
@ -311,10 +316,10 @@ class MigrateTests(MigrationTestBase):
' Raw Python operation -> Grow salamander tail.\n' ' Raw Python operation -> Grow salamander tail.\n'
'migrations.0002_second\n' 'migrations.0002_second\n'
' Create model Book\n' ' Create model Book\n'
' Raw SQL operation -> SELECT * FROM migrations_book\n' " Raw SQL operation -> ['SELECT * FROM migrations_book']\n"
'migrations.0003_third\n' 'migrations.0003_third\n'
' Create model Author\n' ' Create model Author\n'
' Raw SQL operation -> SELECT * FROM migrations_author\n', " Raw SQL operation -> ['SELECT * FROM migrations_author']\n",
out.getvalue() out.getvalue()
) )
# Migrate to the third migration. # Migrate to the third migration.
@ -334,10 +339,10 @@ class MigrateTests(MigrationTestBase):
'Planned operations:\n' 'Planned operations:\n'
'migrations.0003_third\n' 'migrations.0003_third\n'
' Undo Create model Author\n' ' Undo Create model Author\n'
' Raw SQL operation -> SELECT * FROM migrations_book\n' " Raw SQL operation -> ['SELECT * FROM migrations_book']\n"
'migrations.0002_second\n' 'migrations.0002_second\n'
' Undo Create model Book\n' ' Undo Create model Book\n'
' Raw SQL operation -> SELECT * FROM migrations_salamander\n', " Raw SQL operation -> ['SELECT * FROM migrations_salamand…\n",
out.getvalue() out.getvalue()
) )
out = io.StringIO() out = io.StringIO()
@ -349,20 +354,23 @@ class MigrateTests(MigrationTestBase):
' Raw SQL operation -> SELECT * FROM migrations_author WHE…\n', ' Raw SQL operation -> SELECT * FROM migrations_author WHE…\n',
out.getvalue() out.getvalue()
) )
# Migrate to the fourth migration.
call_command('migrate', 'migrations', '0004', verbosity=0)
out = io.StringIO()
# Show the plan when an operation is irreversible. # Show the plan when an operation is irreversible.
call_command('migrate', 'migrations', '0003', plan=True, stdout=out, no_color=True) # Migration 0004's RunSQL uses a SQL string instead of a list, so
self.assertEqual( # sqlparse may be required for splitting.
'Planned operations:\n' if sqlparse or not connection.features.requires_sqlparse_for_splitting:
'migrations.0004_fourth\n' # Migrate to the fourth migration.
' Raw SQL operation -> IRREVERSIBLE\n', call_command('migrate', 'migrations', '0004', verbosity=0)
out.getvalue() out = io.StringIO()
) call_command('migrate', 'migrations', '0003', plan=True, stdout=out, no_color=True)
# Cleanup by unmigrating everything: fake the irreversible, then self.assertEqual(
# migrate all to zero. 'Planned operations:\n'
call_command('migrate', 'migrations', '0003', fake=True, verbosity=0) 'migrations.0004_fourth\n'
' Raw SQL operation -> IRREVERSIBLE\n',
out.getvalue()
)
# Cleanup by unmigrating everything: fake the irreversible, then
# migrate all to zero.
call_command('migrate', 'migrations', '0003', fake=True, verbosity=0)
call_command('migrate', 'migrations', 'zero', verbosity=0) call_command('migrate', 'migrations', 'zero', verbosity=0)
@override_settings(MIGRATION_MODULES={"migrations": "migrations.test_migrations_empty"}) @override_settings(MIGRATION_MODULES={"migrations": "migrations.test_migrations_empty"})

View File

@ -15,6 +15,6 @@ class Migration(migrations.Migration):
('id', models.AutoField(primary_key=True)), ('id', models.AutoField(primary_key=True)),
], ],
), ),
migrations.RunSQL('SELECT * FROM migrations_book', 'SELECT * FROM migrations_salamander') migrations.RunSQL(['SELECT * FROM migrations_book'], ['SELECT * FROM migrations_salamander'])
] ]

View File

@ -15,5 +15,5 @@ class Migration(migrations.Migration):
('id', models.AutoField(primary_key=True)), ('id', models.AutoField(primary_key=True)),
], ],
), ),
migrations.RunSQL('SELECT * FROM migrations_author', 'SELECT * FROM migrations_book') migrations.RunSQL(['SELECT * FROM migrations_author'], ['SELECT * FROM migrations_book'])
] ]