импорт базы данных geonames в postgres для проекта django - проблема с ограничениями внешнего ключа

В базе данных geonames есть две модели, которые ссылаются друг на друга. В базе данных postgres ссылка обеспечивается отношениями внешнего ключа. Проблема заключается в записи данных в базу данных - запись в одну таблицу без ссылки на идентификатор в другой таблице нарушает ограничение внешнего ключа.

Class Geoname
    id = IntegerField(primary_key=True)
    admin_1 = foreignkey('Admin1', null=True, db_index=True)

Class Admin1
    country = models.ForeignKey(Country, db_index=True)
    geoname = models.ForeignKey(Geoname, related_name="admin1_set", db_index=True)

Есть ли способ записи в базу данных postgres с этой схемой, избегая нарушения ограничений внешнего ключа?

Если нет, я думаю, что возможным решением может быть удаление admin_1 из класса geoname, но будет ли django по-прежнему подбирать geoname.admin1_set? Помните, что данные записываются непосредственно в базу данных без ORM - я думаю, что обратные отношения - это то, что создается django ORM - я не знаю, как они представлены на уровне базы данных).


person Cody Django    schedule 25.01.2010    source источник


Ответы (1)


Во-первых: наличие циклической связи в схеме базы данных означает плохой дизайн схемы.

Обратная ссылка действительно создается ORM, но она создается на лету (при чтении), а не при записи.
В противном случае было бы невозможно загрузить фикстуры для автоматических тестов ...

Это взаимно-однозначное отношение? Если это так, вы можете использовать OneToOneField:

Class Geoname
    id = IntegerField(primary_key=True)
    admin_1 = OneToOneField('Admin1')

Class Admin1
    country = models.ForeignKey(Country, db_index=True)

Я надеюсь, что эти классы наследуются от django.db.models.Model в вашем реальном коде!

Если это не однозначное отношение, вы можете сделать это:

Class Geoname
    id = IntegerField(primary_key=True)

Class Admin1
    country = models.ForeignKey(Country, db_index=True)
    geoname = models.ForeignKey(Geoname, db_index=True)

и у вас есть доступ ко всем Admin1 объектам, которые относятся к определенному Geoname

g = Geoname.objects.get(id=1)
g.admin1_set.all() # Returns all Admin1 objects related to Geoname

Вы можете прочитать о таких запросах в документации .

person Felix Kling    schedule 25.01.2010
comment
Спасибо за совет! Я пытаюсь разгадать чужой код - я не был уверен, допустимы ли циклические отношения или они вообще возможны! - person Cody Django; 26.01.2010