#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.

Reply via email to