New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fixed #29198 -- Added --plan
option to migrate command.
#9968
Conversation
03e7513
to
3986f06
Compare
--plan
option to migrate command.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @cgdeboer. Thanks for this. Looking good.
I've rebased, squashed the commits and adjusted the commit message to follow the guidelines.
I just had a couple of comments at this stage...
action = operation.sql if backwards is not True else operation.reverse_sql | ||
prefix = "" | ||
else: | ||
action = "No further Detail" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure about the utility of --> No further Detail
. In this case it might be better to just leave it off.
(Maybe it's useful. Thoughts?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Initially, I was thinking about each action saying at least something to preserve the cadence of the output, but I agree it probably is completely superfluous. I'll remove it.
docs/ref/django-admin.txt
Outdated
.. django-admin-option:: --plan | ||
|
||
Shows the order of unapplied migration operations Django will apply for the | ||
given ``migrate`` command. Unlike the similar ``showmigrations --plan`` |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
@carltongibson thanks for squashing, I added a couple commits to address your comments. |
tests/migrations/test_commands.py
Outdated
self.assertEqual( | ||
"Planned operations:\n" | ||
"migrations.0003_third\n" | ||
" Undo Create model Author --> \n" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know it's slightly more complex but I had imagined we'd not have the -->
if there was nothing after it.
What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fair point, I'll get that cleaned up.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @cgdeboer.
I like this. I think it should be useful.
Are you able to squash the commits again? (It seems like you re-merged master, or the single commit, back into your feature branch: you needed to reset to the branch here that I pushed to.
If your fork is origin
locally:
git fetch origin
git reset --hard origin/ticket_29198
But now we need to squash and git push -f ...
again. Are you able to do that?
)
tests/migrations/test_commands.py
Outdated
" Raw SQL operation --> SELECT * FROM migrations_salamander\n", | ||
out.getvalue() | ||
) | ||
call_command("migrate", "migrations", "zero", verbosity=0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The other test cases have a comment here:
# Cleanup by unmigrating everything
I think that's probably worthwhile (since I did a double-take myself reviewing even now).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll add that , re-squash and get the commit message in line. Long time user, first time contributor (to django), so pardon the missteps, and thanks for your patience.
b874e05
to
1bfb989
Compare
@carltongibson got those comments resolved, commits squashed and cleaned up, etc. Tests are passing locally, not sure if I've done something to offend Jenkins, but he doesn't look completely satisfied. |
@carltongibson let me know if I need that squashin' right. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @cgdeboer.
This looks great.
I just left a couple of small comments. Can you address those and rebase, squash and force push again? (Hopefully the CI run should pass this time: failures are unrelated.)
From there we should be able to get this in. Thanks for the contribution!
docs/ref/django-admin.txt
Outdated
``migrate --plan`` command shows only the migrations, and operations, to be | ||
performed. | ||
|
||
This is intended for users to have an extra sanity check before performing |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not quite sure about the phrasing here. Maybe:
This is intended to allow users to verify operations before performing a more
advanced set of migrations.
tests/migrations/test_commands.py
Outdated
Tests --plan output of migrate command | ||
""" | ||
out = io.StringIO() | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove the blank line.
tests/migrations/test_commands.py
Outdated
call_command("migrate", "migrations", verbosity=0) | ||
|
||
out = io.StringIO() | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove the blank line
@@ -14,6 +14,31 @@ def is_referenced_by_foreign_key(state, model_name_lower, field, field_name): | |||
return False | |||
|
|||
|
|||
def verbose_describe(operation, backwards): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not 100% convinced on the function name here. Maybe someone has a suggestion?
(Maybe it's fine.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK. This looks great. Thanks @cgdeboer.
(The CI failure is unrelated.)
@@ -54,6 +55,10 @@ def add_arguments(self, parser): | |||
'--run-syncdb', action='store_true', | |||
help='Creates tables for apps without migrations.', | |||
) | |||
parser.add_argument( | |||
'--plan', action='store_true', dest='plan', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dest='plan',
is unneeded as that's the default value from --plan
(eac9ab7)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will fix
|
||
if options['plan']: | ||
self.stdout.write("Planned operations:", self.style.MIGRATE_LABEL) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use single quotes throughout the patch except if the string contains a single quote.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I certainly can do that, though I was trying to emulate the pattern seen below in the file in master
.
Lines 156, 187, 192, 195, 309, etc, all use double quotes, even when there are no single quotes.
Please confirm you'd like to shift from that pattern.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, for new code we're trying to follow the style guide.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perfect.
@@ -14,6 +14,31 @@ def is_referenced_by_foreign_key(state, model_name_lower, field, field_name): | |||
return False | |||
|
|||
|
|||
def describe_operation(operation, backwards): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm thinking this would be better organized as a method of the migrate command.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure. I'll move it there.
@@ -14,6 +14,31 @@ def is_referenced_by_foreign_key(state, model_name_lower, field, field_name): | |||
return False | |||
|
|||
|
|||
def describe_operation(operation, backwards): | |||
""" | |||
Returns a string, intended for `stdout.write`, that describes |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
verb style: Return
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will fix
action = "" | ||
prefix = "Undo " if backwards is True else "" | ||
if action is None: | ||
error = True |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This branch is untested.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
True... will fix.
docs/ref/django-admin.txt
Outdated
Shows the order of unapplied migration operations Django will apply for the | ||
given ``migrate`` command. Unlike the similar ``showmigrations --plan`` | ||
command which lists all migrations (even applied ones), the | ||
``migrate --plan`` command shows only the migrations, and operations, to be |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
drop commas around "and operations"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will fix
docs/ref/django-admin.txt
Outdated
``migrate --plan`` command shows only the migrations, and operations, to be | ||
performed. | ||
|
||
This is intended to allow users to verify operations before performing a more |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this sentence adds value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fair enough. I'll rm
it.
else: | ||
action = "{}".format(action.replace("\n", "")) | ||
error = False | ||
action = action if len(action) < 40 else '{}...'.format(action[:37]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add a test for the truncation logic and make sure that all branches in this function are exercised by tests. This could use django.utils.text.Truncator
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll take a look.
@@ -54,6 +55,10 @@ def add_arguments(self, parser): | |||
'--run-syncdb', action='store_true', | |||
help='Creates tables for apps without migrations.', | |||
) | |||
parser.add_argument( | |||
'--plan', action='store_true', dest='plan', | |||
help='Shows a list of ordered migration actions that Django will perform.', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ordered -> the ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just to confirm here. this comment is about the use of the "zero article" vs the "definite article" ? We want:
Shows a list of the ordered migration actions that Django will perform.
Correct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think "ordered" is also unnecessary (i.e. why would they be out of order ;-) ).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Honestly, I thought 'ordered’ would be a good cue. Since the semi-related showmigrations
command does not list migrations in order by default.
I can ditch ordered and we will presume the reader knows that any actions will be ordered
action = "{}".format(action.replace("\n", "")) | ||
error = False | ||
action = action if len(action) < 40 else '{}...'.format(action[:37]) | ||
styled_action = " -> {}".format(action) if action else action |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps this would be simpler:
if action:
action = ' -> ` + string
I don't think the variable name needs to change.
a3d23be
to
035ce94
Compare
@timgraham I think I got all the comments addressed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking better. I force pushed a few cosmetic updates.
How about displaying a message instead just "Planned operations:" if there isn't anything to do?
tests/migrations/test_commands.py
Outdated
@@ -268,6 +268,68 @@ def test_showmigrations_plan(self): | |||
# Cleanup by unmigrating everything | |||
call_command("migrate", "migrations", "zero", verbosity=0) | |||
|
|||
@override_settings(MIGRATION_MODULES={"migrations": "migrations.test_migrations_plan"}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use also use single quotes in the test where possible.
a migration operation. | ||
""" | ||
if hasattr(operation, 'code'): | ||
action = operation.code.__doc__ if not backwards else operation.reverse_code.__doc__ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like operation.reverse_code.__doc__
will fail with AttributeError
if operation.reverse_code
is None
.
2d8ee8b
to
7c9f632
Compare
Following the pattern of other areas of the Planned operations:
No planned migration operations. follows the pattern of: Running migrations:
No migrations to apply. updated and re-pushed |
cdc285b
to
de65aec
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The two fixes look good, but please add tests for them also.
tests/migrations/test_commands.py
Outdated
"""Tests migrate --plan output.""" | ||
out = io.StringIO() | ||
# Show the plan up to the third migration. | ||
call_command("migrate", "migrations", "0003", plan=True, stdout=out, no_color=True) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use single quotes throughout the test.
Done and pushed. |
Summary
Initial Stab at the ticket #29198 (https://code.djangoproject.com/ticket/29198)
Highlights
Fig 1: Forwards
Fig 2: Backwards
Fig 3: Backwards with Warning