Ticket #126 (closed defect: fixed)
unique_together not working with 3 constraints.
| Reported by: | ashc@… | Owned by: | andrew |
|---|---|---|---|
| Priority: | major | Milestone: | 0.5 |
| Component: | migrations | Version: | 0.6-pre |
| Keywords: | Cc: |
Description
from django.db import models
class Foo(models.Model):
desc = models.CharField?(max_length=20)
class Bar(models.Model):
name = models.CharField?(max_length=20)
class SouthStuff?(models.Model):
foo = models.ForeignKey?(Foo)
bar = models.ForeignKey?(Bar)
name = models.CharField?(max_length=20, blank=True)
other = models.IntegerField?()
class Meta:
unique_together = (
('foo', 'bar', 'name',)
)
10:48 ashc@dev-django:[trunk/gapadventures]> python manage.py migrate southtest zero
Running migrations for southtest:
- Migrating backwards to just after zero. < southtest: 0001_initial
Traceback (most recent call last):
File "/home/ashc/sandbox/project_gotham/trunk/gapadventures/./third_party/south/migration.py", line 246, in run_migrations
runfunc(klass.orm)
File "/home/ashc/sandbox/project_gotham/trunk/gapadventures/southtest/migrations/0001_initial.py", line 52, in backwards
db.delete_unique('southtest_southstuff', ['foo_id', 'bar_id', 'name'])
File "/home/ashc/sandbox/project_gotham/trunk/gapadventures/./third_party/south/db/generic.py", line 328, in delete_unique
raise ValueError?("Cannot find a UNIQUE constraint on table %s, columns %r" % (table_name, columns))
ValueError?: Cannot find a UNIQUE constraint on table southtest_southstuff, columns ['foo_id', 'bar_id', 'name']
! Error found during dry run of migration! Aborting.
I have narrowed it down to _constraints_affecting_columns generator always being empty - though I am not familiar enough with generators.
Also noticed that the SQL in the _constraints_affecting_columns method fails. If you remove the kc.table_schema = 'public' part, the constraints are returned, however that isnt enough to fix the problem.
Attachments
Change History
comment:2 Changed 4 years ago by andrew
- Status changed from new to assigned
- Version set to subversion
- Milestone changed from The Future to 0.5
comment:3 Changed 4 years ago by andrew
Right, two comments:
- Firstly, the MySQL library uses DROP INDEX not DROP CONSTRAINT, so the SQL is fine when run via South
- I can't replicate this. I've changed the unique test to include a foreignkey and three columns, and it still works fine.
How did you make the unique constraint in the first place? Was it via django's syncdb (and you later did a migrate --fake)?
It might be helpful if you could attach a schema dump of the database, so I can see what constraints you have.
comment:4 Changed 4 years ago by ashc@…
I have s typescript and sample django app but I can't attach it to this ticket. Is there an I can send it to?
comment:5 Changed 4 years ago by ashc@…
I will also create a typescript of what happens in the app I am currently working on later today.
comment:6 Changed 4 years ago by andrew
You can send the stuff to andrew at aeracode.org if you want.
comment:7 Changed 4 years ago by andrew
- Status changed from assigned to closed
- Resolution set to fixed
Finally! This one is because MySQL migrations use dry runs to check things parse, and delete_unique wasn't dry-run safe. Fixed in [229], with a test that catches the bug.

Also should add that I am using MySQL. Modified the migrate script and replaced:
with:
and noticed that the alter statement isnt even valid for mysql.
mysql> ALTER TABLE southtest_southstuff DROP CONSTRAINT foo_id
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CONSTRAINT foo_id' at line 1