#28824 closed New feature (wontfix)
Allow different Foreign Keys to share same underlying DB column
Reported by: | klass-ivan | Owned by: | nobody |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 1.11 |
Severity: | Normal | Keywords: | foreigh key, db_column, |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
class A(Model): uid = CharField(unique=True) # other fields class B(Model): uid = CharField(unique=True) # other fields class C(Model): # other fields uid = CharField(unique=False) a = ForeignKey(to=A, to_field='uid', db_column='uid', null=True) b = ForeignKey(to=B, to_field='uid', db_column='uid', null=True)
Gives an error:
Field 'b' has column name 'uid' that is used by another field. HINT: Specify a 'db_column' for the field.
However, ForeignKey field is a ORM relation based on underlying column anyway.
I think it won't break anything if we allow different foreign keys to share same underlying column.
This adds more flexibility and will allow better django "on-boarding" process for legacy projects.
It will be also useful when A or B is proxy model - so we can get different proxy objects by different foreign keys referencing same DB row.
Another example can be found here:
https://stackoverflow.com/questions/36911804/django-use-same-column-for-two-foreign-keys
Change History (7)
comment:1 by , 7 years ago
follow-up: 4 comment:2 by , 7 years ago
I'm struggling to see where the value for this change would be, and how common a situation this really is. I think the benefit of supporting this would be outweighed by users that are incorrectly duplicating keys on their models with copy/paste and running into legitimate issues.
Further, I believe you can (probably) get similar behaviour working if you reverse the location of your keys, and switch to using OneToOne. I haven't tested this myself, but I think this would work:
class A(Model): uid = CharField(unique=True) c = OneToOneField(to=C, to_field='uid', db_column='uid', null=True) class B(Model): uid = CharField(unique=True) c = OneToOneField(to=C, to_field='uid', db_column='uid', null=True) class C(Model): # other fields uid = CharField(unique=False) c = get_c(..) c.a # fine c.b # fine
comment:3 by , 7 years ago
Resolution: | → wontfix |
---|---|
Status: | new → closed |
comment:4 by , 4 years ago
Would a valid case for this be to traverse from A to B without joining through C.
A.objects.filter(c__b__name="foo") # below should be more performant than above A.objects.filter(b__name="foo")
I have encountered this same issue. I end up defining the same field on the A model and populating it with the same Value to avoid making unnecessary joins through certain tables. This seems excessive though. It would be nice if I could specify more relationships. If something like the FilteredRelationship was used to define ad-hoc relationships, that could be helpful. It would need better Nested Relationship support though (https://code.djangoproject.com/ticket/29789)
comment:5 by , 4 years ago
Resolution: | wontfix |
---|---|
Status: | closed → new |
Reopening because I think there is a valid case for this, referenced in my previous comment.
comment:6 by , 4 years ago
Resolution: | → wontfix |
---|---|
Status: | new → closed |
Matt, please follow triaging guidelines with regards to wontfix tickets.
Moreover this comment is still valid, even with a use case:
I'm struggling to see where the value for this change would be, and how common a situation this really is. I think the benefit of supporting this would be outweighed by users that are incorrectly duplicating keys on their models with copy/paste and running into legitimate issues.
comment:7 by , 4 years ago
This issue becomes more apparent when creating models on top of existing database just to read from.
If skip
_check_column_name_clashes
in models.base, the next issue will be in_do_insert
- DB error that "Column '<column_name>' specified twice"