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

Функция foreign

Функция foreign помечает колонку как внешний ключ для связи между таблицами. Она используется внутри функции relationship в параметрах primaryjoin и foreign_keys, когда нужно явно указать, какая именно колонка является ссылающейся стороной отношения. Функция принимает один параметр - колонку, которую следует пометить как внешнюю. Возвращает объект ForeignKey, который SQLAlchemy использует при построении условия соединения таблиц.

Синтаксис

foreign(column)

Пример

Давайте создадим две модели, связанные отношением один-ко-многим, и явно укажем внешний ключ через foreign в параметре primaryjoin:

from sqlalchemy import create_engine, ForeignKey, String, select from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship, foreign class Base(DeclarativeBase): pass class User(Base): __tablename__ = 'users' id: Mapped[int] = mapped_column(primary_key=True) name: Mapped[str] = mapped_column(String(50)) articles: Mapped[list['Article']] = relationship( primaryjoin='User.id == foreign(Article.user_id)' ) class Article(Base): __tablename__ = 'articles' id: Mapped[int] = mapped_column(primary_key=True) title: Mapped[str] = mapped_column(String(100)) user_id: Mapped[int] = mapped_column(ForeignKey('users.id')) engine = create_engine('sqlite:///:memory:') Base.metadata.create_all(engine) with engine.connect() as conn: pass

Здесь foreign явно помечает колонку Article.user_id как внешнюю сторону отношения, что позволяет SQLAlchemy правильно построить join.

Пример

Давайте заполним таблицы данными и проверим работу связи, созданной через foreign:

from sqlalchemy import create_engine, ForeignKey, String from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship, foreign, Session class Base(DeclarativeBase): pass class User(Base): __tablename__ = 'users' id: Mapped[int] = mapped_column(primary_key=True) name: Mapped[str] = mapped_column(String(50)) articles: Mapped[list['Article']] = relationship( primaryjoin='User.id == foreign(Article.user_id)' ) class Article(Base): __tablename__ = 'articles' id: Mapped[int] = mapped_column(primary_key=True) title: Mapped[str] = mapped_column(String(100)) user_id: Mapped[int] = mapped_column(ForeignKey('users.id')) engine = create_engine('sqlite:///:memory:') Base.metadata.create_all(engine) with Session(engine) as session: user = User(name='user') user.articles = [ Article(title='article 1'), Article(title='article 2'), ] session.add(user) session.commit() res = session.execute(select(User)).scalar_one() print([a.title for a in res.articles])

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

['article 1', 'article 2']

Пример

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

from sqlalchemy import create_engine, ForeignKey, String from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship, foreign class Base(DeclarativeBase): pass class User(Base): __tablename__ = 'users' id: Mapped[int] = mapped_column(primary_key=True) name: Mapped[str] = mapped_column(String(50)) class Article(Base): __tablename__ = 'articles' id: Mapped[int] = mapped_column(primary_key=True) title: Mapped[str] = mapped_column(String(100)) author_id: Mapped[int] = mapped_column(ForeignKey('users.id')) editor_id: Mapped[int] = mapped_column(ForeignKey('users.id')) author: Mapped['User'] = relationship( foreign_keys=[author_id], primaryjoin='User.id == foreign(Article.author_id)' ) engine = create_engine('sqlite:///:memory:') Base.metadata.create_all(engine) with engine.connect() as conn: pass

Здесь модель Article содержит две колонки с внешними ключами на таблицу users, и foreign помогает однозначно определить, какая из них используется в конкретном отношении.

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

  • функцию relationship,
    которая настраивает связи между моделями
  • функцию remote,
    которая помечает колонку как удаленную сторону отношения
  • функцию backref,
    которая создает обратную ссылку в отношении
  • функцию joinedload,
    которая жадно загружает связанные объекты через JOIN
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить