#2257 closed defect (fixed)
[patch] syncdb should generate unique constraint names with hashes
Reported by: | Owned by: | Malcolm Tredinnick | |
---|---|---|---|
Component: | Core (Management commands) | Version: | |
Severity: | normal | Keywords: | |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Take a look at how syncdb names constraints:
backend.quote_name('%s_referencing_%s_%s' % (r_col, table, col))
In some circumstances, syncdb generates the same constraint name (for foreign keys= for different tables. Now, using both table names in the name can lead to too long names, so this isn't a solution. I propose to use a hash of both table names + the two attribute names. A quick, easy and dirty version is:
backend.quote_name('%s_referencing_%s_%x' % (r_col, col, hash((r_table, table))))
Here's an example.
class Man(models.Model): father = ForeignKey(Man, null=True) class Woman(models.Model): father = ForeignKey(Man, null=True)
These will (currently) both create the constraint 'father_referencing_man_id' (resulting in incomprehensible error message in case of mysql)
Attachments (1)
Change History (7)
comment:1 by , 18 years ago
Owner: | changed from | to
---|
comment:2 by , 18 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
comment:3 by , 18 years ago
Resolution: | fixed |
---|---|
Status: | closed → reopened |
David Avraamides pointed out (politely) that I suck. The solution in [3373] only works when all references are generated at the same time. I'll write a better fix shortly; reopening for now, since people seem to be hitting this about once a day.
by , 18 years ago
Attachment: | 2257_fullname_1.patch added |
---|
supplies db wide unique fk names (for mysql)
comment:4 by , 18 years ago
Summary: | syncdb should generate unique constraint names with hashes → [patch] syncdb should generate unique constraint names with hashes |
---|
patch produces unique fk names. This one uses the full table names in the fk name (I have another that uses the col names and hashes the two tablenames at the end if you want it). The memo dict reference_names has been taken out.
comment:5 by , 18 years ago
Resolution: | → fixed |
---|---|
Status: | reopened → closed |
comment:6 by , 18 years ago
Thanks for the patch, Bill, but I ended up going with a hash of the table names at the end, just to save a few characters.
For people reading this in the future, the reason I am not just punting this and using no name so that MySQL can make on up is because it makes debugging a little easier to see a constraint name that makes sense when you violate it. It's worth a little pain to try and get that right.
The auto-closer doesn't seem to want to pick this up (in [3373]):
Fixed #2257 -- MySQL wants constraint names to be unique per-database, so fixed
the SQL generation to ensure this.