Отношение Django к двум столбцам базы данных
Я использую django для взаимодействия с существующей базой данных, над которой у меня нет контроля.
База данных часто использует несколько столбцов для создания отношений и имеет уникальность для всех этих столбцов.
Генератор моделей django inspectdb
правильно определил их как unique_together = (('foo', 'bar'), ('foo', 'bar'),)
, в результате чего получилась следующая модель:
class A(models.Model):
foo = models.IntegerField(db_column='FOO', primary_key=True)
bar = models.IntegerField(db_column='BAR')
class Meta:
managed = False
db_table = 'A'
unique_together = (('foo', 'bar'), ('foo', 'bar'),)
Теперь есть другая таблица, записи которой относятся к этой таблице по обоим столбцам. При запросе с помощью SQL я бы связал их следующим образом:
SELECT * FROM A LEFT JOIN B ON A.foo = B.foo AND A.bar = B.bar
Однако inspectdb
не удалось корректно отобразить два столбца, используемых в связанной таблице:
class B(models.Model):
foo = models.OneToOneField(A, models.DO_NOTHING, db_column='A', primary_key=True)
bar = models.ForeignKey(A, models.DO_NOTHING, db_column='A')
Выше приведено то, что он сгенерировал, однако в действительности это отношение «многие-к-одному» к таблице A. Это приводит к ошибке во время выполнения, поскольку столбец bar
в таблице A
не является уникальным.
Могу ли я как-то определить эти отношения в модели django?
И как мне сделать эффективный запрос, чтобы django сгенерировал выражение JOIN
с двумя условиями?
Композитные ключи не могут быть связаны с в Django. Однако проверьте упоминание ForeignObject
в той статье, но обратите внимание на явное предупреждение, которое там дается.
Вероятно, вы можете создать грязное обходное решение, чтобы заставить вашу выборку работать относительно простым способом, но оно не сохранит управление отношениями в ORM:
class B(models.Model):
foo = models.IntegerField()
bar = models.IntegerField()
b = B.objects.first()
a = A.objects.filter(foo=b.foo, bar=b.bar)