РЕПЕТИТОР математика физика информатика
Для школьников и студентов. Подтягивание пробелов. ЦЭ, ЦТ, ОГЭ, ЕГЭ.
Идет набор на ЛЕТО. Жмите для подробностей:)
706 of 711 menu

Исключение AmbiguousForeignKeysError

Исключение AmbiguousForeignKeysError наследуется от ArgumentError и возникает при попытке автоматически определить связь между двумя таблицами, когда между ними существует более одного внешнего ключа. SQLAlchemy не может самостоятельно выбрать, какой именно внешний ключ использовать для построения отношения, поэтому выбрасывает это исключение с требованием указать ключ явно через параметр foreign_keys или primaryjoin.

Чаще всего исключение появляется при работе с функцией relationship, когда две таблицы связаны несколькими внешними ключами. Например, таблица сообщений может содержать одновременно идентификатор отправителя и идентификатор получателя, оба ссылаются на таблицу пользователей.

Синтаксис

from sqlalchemy.exc import AmbiguousForeignKeysError try: # код, вызывающий ошибку pass except AmbiguousForeignKeysError as exc: print(exc)

Пример

Давайте создадим две таблицы с двумя внешними ключами и попробуем построить связь через relationship без указания конкретного ключа:

from sqlalchemy import create_engine, ForeignKey from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship class Base(DeclarativeBase): pass class User(Base): __tablename__ = 'users' id: Mapped[int] = mapped_column(primary_key=True) title: Mapped[str] class Article(Base): __tablename__ = 'articles' id: Mapped[int] = mapped_column(primary_key=True) title: Mapped[str] author_id: Mapped[int] = mapped_column(ForeignKey('users.id')) editor_id: Mapped[int] = mapped_column(ForeignKey('users.id')) author = relationship('User') engine = create_engine('sqlite:///:memory:') Base.metadata.create_all(engine)

При выполнении кода будет выброшено исключение AmbiguousForeignKeysError, потому что между таблицами articles и users существует два внешних ключа:

sqlalchemy.exc.AmbiguousForeignKeysError: Could not determine join condition between parent/child tables on relationship Article.author - there are multiple foreign key paths linking the tables. Specify the 'foreign_keys' argument, providing a list of those columns which should be counted as containing a foreign key reference to the parent table.

Пример

Исправим ошибку, указав конкретный внешний ключ через параметр foreign_keys:

from sqlalchemy import create_engine, ForeignKey from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship class Base(DeclarativeBase): pass class User(Base): __tablename__ = 'users' id: Mapped[int] = mapped_column(primary_key=True) title: Mapped[str] class Article(Base): __tablename__ = 'articles' id: Mapped[int] = mapped_column(primary_key=True) title: Mapped[str] author_id: Mapped[int] = mapped_column(ForeignKey('users.id')) editor_id: Mapped[int] = mapped_column(ForeignKey('users.id')) author = relationship('User', foreign_keys=[author_id]) engine = create_engine('sqlite:///:memory:') Base.metadata.create_all(engine) print("tables created")

Результат выполнения кода:

"tables created"

Пример

Альтернативный способ - указать условие соединения явно через параметр primaryjoin:

from sqlalchemy import create_engine, ForeignKey from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship class Base(DeclarativeBase): pass class User(Base): __tablename__ = 'users' id: Mapped[int] = mapped_column(primary_key=True) title: Mapped[str] class Article(Base): __tablename__ = 'articles' id: Mapped[int] = mapped_column(primary_key=True) title: Mapped[str] author_id: Mapped[int] = mapped_column(ForeignKey('users.id')) editor_id: Mapped[int] = mapped_column(ForeignKey('users.id')) author = relationship('User', primaryjoin='Article.author_id == User.id') engine = create_engine('sqlite:///:memory:') Base.metadata.create_all(engine) print("tables created")

Результат выполнения кода:

"tables created"

Смотрите также

  • исключение ArgumentError,
    родительский класс для ошибок аргументов
  • исключение NoForeignKeysError,
    которое возникает при отсутствии внешних ключей
  • исключение NoReferencedTableError,
    которое возникает при отсутствии связанной таблицы
  • исключение InvalidRequestError,
    которое сигнализирует о некорректном запросе
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить