Sqlalchemy One - Много и Один-Один в одном столе - PullRequest
0 голосов
/ 28 августа 2018

У меня есть две модели: пользователь и группа.

Пользователь может быть в одной группе так:

class User(db.Model):
    # other fields
    group_id = db.Column(db.Integer(), db.ForeignKey('group.id'))

но с другой стороны, у меня также есть некоторая информация о пользователе, который создает эту конкретную группу:

class Group(db.Model):
    # other fields
    users = db.relationship("User", backref='group')
    created_by = db.Column(db.Integer(), db.ForeignKey('user.id'))

Результат:

sqlalchemy.exc.CircularDependencyError: Can't sort tables for DROP; an unresolvable foreign key dependency exists between tables: group, user.  Please ensure that the ForeignKey and ForeignKeyConstraint objects involved in the cycle have names so that they can be dropped using DROP CONSTRAINT.

Я пытался use_alter=True, но это дает мне:

sqlalchemy.exc.CompileError: Can't emit DROP CONSTRAINT for constraint ForeignKeyConstraint(

1 Ответ

0 голосов
/ 28 августа 2018

Интересно, я бы ожидал, что вы получите AmbiguousForeignKeyError, но вместо этого вы, кажется, получите CircularDependencyError? Согласно документам это вызвано двумя сценариями:

  • В операции очистки сеанса, если два объекта взаимно зависят друг от друга, они не могут быть вставлены или удалены через INSERT или УДАЛИТЬ только заявления; ОБНОВЛЕНИЕ потребуется для пост-ассоциированного или предварительно деассоциировать одно из ограниченных значений внешнего ключа. флаг post_update, описанный в строках, указывающих на себя / взаимно Зависимые строки могут разрешить этот цикл.
  • В MetaData.sorted_tables операция, два объекта ForeignKey или ForeignKeyConstraint взаимно ссылаются друг на друга. Примените флаг use_alter = True к одному или обоим, см. Создание / удаление ограничений внешнего ключа через ALTER.

Я не уверен, что вы выполняете именно эту ошибку, но, скорее всего, вы сможете решить ее, решив неоднозначную ссылку.

Неоднозначная ссылка связана с тем, что SQLAlchemy не может выяснить, как выполнить объединение при наличии нескольких ссылок (в данном случае users и creation_by). Эту проблему можно решить, указав, как следует связать взаимосвязь, что можно сделать либо путем предоставления конкретного внешнего ключа, который он должен использовать, либо путем явного определения условия соединения.

Вы можете увидеть, как они применяются к вашему примеру здесь:

class User(Base):
    # Other setup / fields

    group_id = Column(Integer, ForeignKey('group.id'))

class Group(Base):
    # Other setup / fields

    created_by_id = Column(Integer, ForeignKey('user.id'), nullable=False)
    created_by = relationship("User", foreign_keys=[created_by_id])
    users = relationship("User", backref="group", primaryjoin=id==User.group_id)

Документация о связях отношений: http://docs.sqlalchemy.org/en/latest/orm/join_conditions.html#configuring-how-relationship-joins

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...