Opened 5 years ago
Last modified 4 months ago
#31834 assigned Bug
Cannot sqlmigrate on Django migrations that change unique_together
| Reported by: | Brіаn Lаі | Owned by: | Bishnu Bhattarai |
|---|---|---|---|
| Component: | Migrations | Version: | 3.0 |
| Severity: | Normal | Keywords: | sqlmigrate |
| Cc: | Triage Stage: | Accepted | |
| Has patch: | yes | Needs documentation: | no |
| Needs tests: | yes | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description (last modified by )
Somewhat similar to #26624, but forward sqlmigrate, reproduced on Django 3.0.8 and Postgres 10.x.
If a model has a unique_together of
unique_together = [
(a, b)
]
and it becomes
unique_together = [
(a, b, c)
]
, although the makemigrations command successfully generates a new migration with the corresponding AlterUniqueTogether() operation, the migration cannot be inspected with the sqlmigrate command.
Reproduce bug with the following (the project may also be attached)
class Model1(models.Model):
id = models.IntegerField(primary_key=True)
name = models.CharField(max_length=255, unique=True)
class Model2(models.Model):
id = models.IntegerField(primary_key=True)
link_id = models.CharField(max_length=255)
settings = models.ForeignKey(Model1, on_delete=models.CASCADE)
class Model3(models.Model):
id = models.IntegerField(primary_key=True)
order = models.IntegerField()
model_2 = models.ForeignKey(Model2, on_delete=models.CASCADE)
direct = models.BooleanField(default=True)
class Meta:
unique_together = [
('model_2', 'order')
# To get the bug, change this to ('model_2', 'order', 'direct') and sqlmigrate the migration that this creates.
]
The error shown in the terminal is:
Traceback (most recent call last):
File "manage.py", line 22, in <module>
execute_from_command_line(sys.argv)
File "/lib/python3.6/site-packages/django/core/management/__init__.py", line 401, in execute_from_command_line
utility.execute()
File "/lib/python3.6/site-packages/django/core/management/__init__.py", line 395, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/lib/python3.6/site-packages/django/core/management/base.py", line 328, in run_from_argv
self.execute(*args, **cmd_options)
File "/lib/python3.6/site-packages/django/core/management/commands/sqlmigrate.py", line 30, in execute
return super().execute(*args, **options)
File "/lib/python3.6/site-packages/django/core/management/base.py", line 369, in execute
output = self.handle(*args, **options)
File "/lib/python3.6/site-packages/django/core/management/commands/sqlmigrate.py", line 65, in handle
sql_statements = executor.collect_sql(plan)
File "/lib/python3.6/site-packages/django/db/migrations/executor.py", line 225, in collect_sql
state = migration.apply(state, schema_editor, collect_sql=True)
File "/lib/python3.6/site-packages/django/db/migrations/migration.py", line 124, in apply
operation.database_forwards(self.app_label, schema_editor, old_state, project_state)
File "/lib/python3.6/site-packages/django/db/migrations/operations/models.py", line 525, in database_forwards
getattr(new_model._meta, self.option_name, set()),
File "/lib/python3.6/site-packages/django/db/backends/base/schema.py", line 380, in alter_unique_together
self._delete_composed_index(model, fields, {'unique': True}, self.sql_delete_unique)
File "/lib/python3.6/site-packages/django/db/backends/base/schema.py", line 414, in _delete_composed_index
", ".join(columns),
ValueError: Found wrong number (0) of constraints for bar_model3(model_2, order)
Attachments (1)
Change History (11)
by , 5 years ago
| Attachment: | foo.tar.gz added |
|---|
comment:1 by , 5 years ago
| Description: | modified (diff) |
|---|
comment:2 by , 5 years ago
| Description: | modified (diff) |
|---|
comment:3 by , 5 years ago
| Component: | Database layer (models, ORM) → Migrations |
|---|---|
| Resolution: | → duplicate |
| Status: | new → closed |
I think we can mark this as a duplicate of #26624, because they have the same cause. In both scenarios a constraint doesn't exist in the database and cannot be introspected, sqlmigrate works properly if you first apply a migration which adds a constraint.
comment:4 by , 5 years ago
I guess so. However you choose to triage and/or fix the item, I hope I am providing additional context by saying this bug can be reproduced with SQLite, whereas #26624 claims they could not.
comment:5 by , 5 months ago
| Resolution: | duplicate |
|---|---|
| Status: | closed → new |
| Triage Stage: | Unreviewed → Accepted |
#26624 was wontfix'ed by scoping it to the deprecated index_together, but since this report is for unique_together, it should be valid now.
comment:6 by , 4 months ago
| Owner: | changed from to |
|---|---|
| Status: | new → assigned |
I am interested in this ticket, I want to assign this ticket myself.
comment:7 by , 4 months ago
I have created a PR for this issue and have fixed from manual testing,
But writing test case for this type of fix looks a bit complicated, Could you please provide me some example of test case for sqlmigrate and in which file is the best place to keep this test.
here is the PR https://github.com/django/django/pull/19590
comment:8 by , 4 months ago
| Has patch: | set |
|---|
comment:9 by , 4 months ago
| Needs tests: | set |
|---|
Hi Bishnu. Thanks for your work on this ticket. If you are still looking for where to write your test, the file djangoproject/tests/migrations/test_commands.py has the existing sqlmigrate tests as well as others. There a lot of good examples to follow in that file which include work on tickets for a different command.
comment:10 by , 4 months ago
Thank you for your sweet answer, I will add relevant test cases and will update you soon.
Bug demo project