Класс ForeignKey
Класс ForeignKey определяет внешний ключ
для столбца таблицы. Первым параметром
передается целевой столбец в виде строки
формата имя_таблицы.имя_столбца.
Внешний ключ связывает столбец текущей таблицы
со столбцом другой таблицы и обеспечивает
ссылочную целостность данных на уровне СУБД.
Синтаксис
ForeignKey(column)
Пример
Давайте создадим две таблицы users и
articles, где столбец user_id
таблицы статей ссылается на столбец id
таблицы пользователей:
from sqlalchemy import create_engine, ForeignKey
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
class Base(DeclarativeBase):
pass
class User(Base):
__tablename__ = 'users'
id: Mapped[int] = mapped_column(primary_key=True)
name: Mapped[str]
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'))
engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
print(Article.__table__.c.user_id.foreign_keys)
Результат выполнения кода:
{ForeignKey('users.id')}
Пример
Давайте посмотрим, как выглядит SQL-запрос создания таблицы с внешним ключом:
from sqlalchemy import create_engine, ForeignKey
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
from sqlalchemy.schema import CreateTable
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'))
engine = create_engine('sqlite:///:memory:')
print(CreateTable(Article.__table__).compile(engine))
Итоговый SQL запрос:
CREATE TABLE articles (
id INTEGER NOT NULL,
title VARCHAR NOT NULL,
user_id INTEGER NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY(user_id) REFERENCES users (id)
)
Пример
Давайте вставим связанные данные и убедимся, что внешний ключ работает:
<+python+>
from sqlalchemy import create_engine, ForeignKey
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, Session
class Base(DeclarativeBase):
pass
class User(Base):
__tablename__ = 'users'
id: Mapped[int] = mapped_column(primary_key=True)
name: Mapped[str]
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'))
engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
with Session(engine) as session:
user = User(id=1, name='user')
article = Article(id=1, title='article', user_id=1)
session.add_all([user, article])
session.commit()
res = session.query(Article).first()
print(res.title, res.user_id)
<-python+>
Результат выполнения кода:
"article 1"
Смотрите также
-
метод
references,
который возвращает столбец, на который ссылается внешний ключ -
метод
get_referent,
который возвращает объект, на который указывает внешний ключ -
атрибут
column,
который хранит целевой столбец внешнего ключа -
атрибут
ondelete,
который задает поведение при удалении связанной записи