#34510: sqlmigrate does not follows replaces in squashed migrations
-------------------------------------+-------------------------------------
Reporter: NeodymiumFerBore | Owner: nobody
Type: Uncategorized | Status: new
Component: Core (Management | Version: 4.2
commands) |
Severity: Normal | Resolution:
Keywords: squashed migration | Triage Stage:
replaces sqlmigrate command core | Unreviewed
management |
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by NeodymiumFerBore):
* type: Bug => Uncategorized
Old description:
> Hello!
>
> The `sqlmigrate` command does not follow `replaces` in squashed
> migration, with original (squashed) migration files deleted. This ticket
> is roughly the same than #33583. In #31318, the issue is marked as solved
> with commit
> [https://github.com/django/django/commit/d88365708c554efe3c786c3be6da1d9de916360f
> d883657]. Since then, `MigrationLoader` accepts the argument
> `replace_migrations`. However,
> [https://github.com/django/django/blob/d88365708c554efe3c786c3be6da1d9de916360f/django/core/management/commands/sqlmigrate.py#L37
> the loader instance here] has this option to `False`. I don't see a
> command option to set it to `True`.
>
> Sample error (not mine, but actually the exact same, taken from #33583):
>
> {{{
> python3 manage.py sqlmigrate beta 0003
> Traceback (most recent call last):
> File "/Users/amin/sandbox/mysite/manage.py", line 22, in <module>
> main()
> File "/Users/amin/sandbox/mysite/manage.py", line 18, in main
> execute_from_command_line(sys.argv)
> File "/usr/local/lib/python3.9/site-
> packages/django/core/management/__init__.py", line 446, in
> execute_from_command_line
> utility.execute()
> File "/usr/local/lib/python3.9/site-
> packages/django/core/management/__init__.py", line 440, in execute
> self.fetch_command(subcommand).run_from_argv(self.argv)
> File "/usr/local/lib/python3.9/site-
> packages/django/core/management/base.py", line 414, in run_from_argv
> self.execute(*args, **cmd_options)
> File "/usr/local/lib/python3.9/site-
> packages/django/core/management/commands/sqlmigrate.py", line 38, in
> execute
> return super().execute(*args, **options)
> File "/usr/local/lib/python3.9/site-
> packages/django/core/management/base.py", line 460, in execute
> output = self.handle(*args, **options)
> File "/usr/local/lib/python3.9/site-
> packages/django/core/management/commands/sqlmigrate.py", line 46, in
> handle
> loader = MigrationLoader(connection, replace_migrations=False)
> File "/usr/local/lib/python3.9/site-
> packages/django/db/migrations/loader.py", line 58, in __init__
> self.build_graph()
> File "/usr/local/lib/python3.9/site-
> packages/django/db/migrations/loader.py", line 276, in build_graph
> self.graph.validate_consistency()
> File "/usr/local/lib/python3.9/site-
> packages/django/db/migrations/graph.py", line 198, in
> validate_consistency
> [n.raise_error() for n in self.node_map.values() if isinstance(n,
> DummyNode)]
> File "/usr/local/lib/python3.9/site-
> packages/django/db/migrations/graph.py", line 198, in <listcomp>
> [n.raise_error() for n in self.node_map.values() if isinstance(n,
> DummyNode)]
> File "/usr/local/lib/python3.9/site-
> packages/django/db/migrations/graph.py", line 60, in raise_error
> raise NodeNotFoundError(self.error_message, self.key,
> origin=self.origin)
> django.db.migrations.exceptions.NodeNotFoundError: Migration
> beta.0001_initial dependencies reference nonexistent parent node
> ('first', '0001_initial')
> }}}
>
> I tried to set it to `True` manually in 4.1.7, and it successfully showed
> SQL queries involved in the migration I wanted to inspect.
> `sqlmigrate.py` has not changed between 4.1.7 and 4.2, so I guess it also
> affects it.
>
> [https://github.com/django/django/blob/4.1.7/django/core/management/commands/sqlmigrate.py#L46
> Link: MigrationLoader instance in 4.1.7 L46]
> [https://github.com/django/django/blob/4.2/django/core/management/commands/sqlmigrate.py#L46
> Link: MigrationLoader instance in 4.2 L46]
> [https://github.com/django/django/blob/main/django/core/management/commands/sqlmigrate.py#L46
> Link: MigrationLoader instance in main L46]
>
> I see that it always has been like this since commit `d883657`. Now maybe
> I don't understand why it works like so. Could you explain why it is set
> to `False` with no option to set it to `True` in `sqlmigrate`? Is it
> unreliable? In #33583, someone said:
>
> > `replaces` is documented and supported only for ​squashing migrations
> so described flow was never officially supported
>
> Why not adding a command option to `sqlmigrate` to enable following
> `replaces` in squashed migration, with a warning like "experimental" or
> something?
>
> Thank you.
New description:
Hello!
I actually don't know if this issue will end being a bug, a new feature or
a documentation improvement.
The `sqlmigrate` command does not follow `replaces` in squashed migration,
with original (squashed) migration files deleted. This ticket is roughly
the same than #33583. In #31318, the issue is marked as solved with commit
[https://github.com/django/django/commit/d88365708c554efe3c786c3be6da1d9de916360f
d883657]. Since then, `MigrationLoader` accepts the argument
`replace_migrations`. However,
[https://github.com/django/django/blob/d88365708c554efe3c786c3be6da1d9de916360f/django/core/management/commands/sqlmigrate.py#L37
the loader instance here] has this option to `False`. I don't see a
command option to set it to `True`.
Sample error (not mine, but actually the exact same, taken from #33583):
{{{
python3 manage.py sqlmigrate beta 0003
Traceback (most recent call last):
File "/Users/amin/sandbox/mysite/manage.py", line 22, in <module>
main()
File "/Users/amin/sandbox/mysite/manage.py", line 18, in main
execute_from_command_line(sys.argv)
File "/usr/local/lib/python3.9/site-
packages/django/core/management/__init__.py", line 446, in
execute_from_command_line
utility.execute()
File "/usr/local/lib/python3.9/site-
packages/django/core/management/__init__.py", line 440, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/usr/local/lib/python3.9/site-
packages/django/core/management/base.py", line 414, in run_from_argv
self.execute(*args, **cmd_options)
File "/usr/local/lib/python3.9/site-
packages/django/core/management/commands/sqlmigrate.py", line 38, in
execute
return super().execute(*args, **options)
File "/usr/local/lib/python3.9/site-
packages/django/core/management/base.py", line 460, in execute
output = self.handle(*args, **options)
File "/usr/local/lib/python3.9/site-
packages/django/core/management/commands/sqlmigrate.py", line 46, in
handle
loader = MigrationLoader(connection, replace_migrations=False)
File "/usr/local/lib/python3.9/site-
packages/django/db/migrations/loader.py", line 58, in __init__
self.build_graph()
File "/usr/local/lib/python3.9/site-
packages/django/db/migrations/loader.py", line 276, in build_graph
self.graph.validate_consistency()
File "/usr/local/lib/python3.9/site-
packages/django/db/migrations/graph.py", line 198, in validate_consistency
[n.raise_error() for n in self.node_map.values() if isinstance(n,
DummyNode)]
File "/usr/local/lib/python3.9/site-
packages/django/db/migrations/graph.py", line 198, in <listcomp>
[n.raise_error() for n in self.node_map.values() if isinstance(n,
DummyNode)]
File "/usr/local/lib/python3.9/site-
packages/django/db/migrations/graph.py", line 60, in raise_error
raise NodeNotFoundError(self.error_message, self.key,
origin=self.origin)
django.db.migrations.exceptions.NodeNotFoundError: Migration
beta.0001_initial dependencies reference nonexistent parent node ('first',
'0001_initial')
}}}
I tried to set it to `True` manually in 4.1.7, and it successfully showed
SQL queries involved in the migration I wanted to inspect. `sqlmigrate.py`
has not changed between 4.1.7 and 4.2, so I guess it also affects it.
[https://github.com/django/django/blob/4.1.7/django/core/management/commands/sqlmigrate.py#L46
Link: MigrationLoader instance in 4.1.7 L46]
[https://github.com/django/django/blob/4.2/django/core/management/commands/sqlmigrate.py#L46
Link: MigrationLoader instance in 4.2 L46]
[https://github.com/django/django/blob/main/django/core/management/commands/sqlmigrate.py#L46
Link: MigrationLoader instance in main L46]
I see that it always has been like this since commit `d883657`. Now maybe
I don't understand why it works like so. Could you explain why it is set
to `False` with no option to set it to `True` in `sqlmigrate`? Is it
unreliable? In #33583, someone said:
> `replaces` is documented and supported only for ​squashing migrations so
described flow was never officially supported
Why not adding a command option to `sqlmigrate` to enable following
`replaces` in squashed migration, with a warning like "experimental" or
something?
Thank you.
--
--
Ticket URL: <https://code.djangoproject.com/ticket/34510#comment:3>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/01070187aba1e404-b1e9fc10-e099-48d1-95bc-10dc5db2f88e-000000%40eu-central-1.amazonses.com.