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

Исключение NoForeignKeysError

Исключение NoForeignKeysError относится к семейству ArgumentError и наследуется от него. Оно возникает в тот момент, когда SQLAlchemy пытается автоматически определить условие соединения (join condition) между двумя таблицами, но не находит между ними ни одного общего внешнего ключа. Чаще всего это происходит при вызове relationship без явного указания primaryjoin или foreign_keys, а также при использовании Query.join между таблицами, у которых нет настоящей связи по внешнему ключу.

Исключение не принимает дополнительных параметров при создании: в конструктор передаётся только текст сообщения об ошибке. Перехватывать его удобнее всего через базовый класс ArgumentError или через корневой SQLAlchemyError.

Синтаксис

from sqlalchemy.exc import NoForeignKeysError raise NoForeignKeysError("Could not find a foreign key relationship")

Пример

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

from sqlalchemy import create_engine, ForeignKey from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship, Session from sqlalchemy.exc import NoForeignKeysError class Base(DeclarativeBase): pass class Article(Base): __tablename__ = 'articles' id: Mapped[int] = mapped_column(primary_key=True) title: Mapped[str] class User(Base): __tablename__ = 'users' id: Mapped[int] = mapped_column(primary_key=True) name: Mapped[str] # no foreign key to articles articles: Mapped[list['Article']] = relationship() engine = create_engine('sqlite:///:memory:') Base.metadata.create_all(engine) try: with Session(engine) as session: session.query(User).join(Article).all() except NoForeignKeysError as e: print('NoForeignKeysError:', e)

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

"NoForeignKeysError: Could not find a foreign key relationship between 'users' and 'articles'"

Пример

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

from sqlalchemy import create_engine, ForeignKey from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship, Session class Base(DeclarativeBase): pass class Article(Base): __tablename__ = 'articles' id: Mapped[int] = mapped_column(primary_key=True) title: Mapped[str] user_id: Mapped[int] = mapped_column(ForeignKey('users.id')) class User(Base): __tablename__ = 'users' id: Mapped[int] = mapped_column(primary_key=True) name: Mapped[str] articles: Mapped[list['Article']] = relationship() engine = create_engine('sqlite:///:memory:') Base.metadata.create_all(engine) with Session(engine) as session: user = User(name='user') user.articles.append(Article(title='article')) session.add(user) session.commit() res = session.query(User).join(Article).all() print([u.name for u in res])

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

['user']

Пример

Давайте перехватим исключение через базовый класс ArgumentError и выведем его тип:

from sqlalchemy import create_engine, ForeignKey from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship, Session from sqlalchemy.exc import ArgumentError, NoForeignKeysError class Base(DeclarativeBase): pass class Article(Base): __tablename__ = 'articles' id: Mapped[int] = mapped_column(primary_key=True) title: Mapped[str] class User(Base): __tablename__ = 'users' id: Mapped[int] = mapped_column(primary_key=True) name: Mapped[str] articles: Mapped[list['Article']] = relationship() engine = create_engine('sqlite:///:memory:') Base.metadata.create_all(engine) try: with Session(engine) as session: session.query(User).join(Article).all() except ArgumentError as e: print(type(e).__name__) print(isinstance(e, NoForeignKeysError))

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

"NoForeignKeysError" "True"

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

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