Атрибут name класса ForeignKey
Атрибут name класса ForeignKey задает
имя ограничения внешнего ключа. Первым параметром
в конструктор ForeignKey передается столбец,
на который ссылается внешний ключ, а параметром
name можно явно указать имя этого ограничения.
Если имя не задано, SQLAlchemy сгенерирует его
автоматически на основе имени таблицы и столбца.
Явное имя полезно, когда нужно сослаться на
ограничение в миграциях, удалить его через
ALTER TABLE или согласовать схему с уже
существующей базой данных, где имена ограничений
заданы вручную.
Синтаксис
ForeignKey(column, name='constraint_name')
Пример
Давайте создадим модель с внешним ключом и явным именем ограничения:
from sqlalchemy import ForeignKey
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
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', name='fk_articles_user_id')
)
class User(Base):
__tablename__ = 'users'
id: Mapped[int] = mapped_column(primary_key=True)
name: Mapped[str]
Теперь ограничение внешнего ключа в таблице
articles будет называться
fk_articles_user_id.
Пример
Давайте прочитаем заданное имя через атрибут
name объекта ForeignKey:
from sqlalchemy import ForeignKey, Table, Column, Integer, MetaData
metadata = MetaData()
users = Table(
'users', metadata,
Column('id', Integer, primary_key=True),
)
articles = Table(
'articles', metadata,
Column('id', Integer, primary_key=True),
Column('user_id', Integer, ForeignKey('users.id', name='fk_articles_user_id')),
)
fk = list(articles.c.user_id.foreign_keys)[0]
print(fk.name)
Результат выполнения кода:
"fk_articles_user_id"
Пример
Давайте посмотрим, какое имя SQLAlchemy сгенерирует
автоматически, если не задавать параметр name:
from sqlalchemy import ForeignKey, Table, Column, Integer, MetaData
metadata = MetaData()
users = Table(
'users', metadata,
Column('id', Integer, primary_key=True),
)
articles = Table(
'articles', metadata,
Column('id', Integer, primary_key=True),
Column('user_id', Integer, ForeignKey('users.id')),
)
fk = list(articles.c.user_id.foreign_keys)[0]
print(fk.name)
Результат выполнения кода:
None
Как видно, при автоматической генерации атрибут
name возвращает None. Имя ограничения
в этом случае формируется диалектом СУБД при
создании таблицы.
Пример
Давайте создадим таблицы и увидим имя ограничения в итоговом SQL-запросе:
from sqlalchemy import ForeignKey, Table, Column, Integer, MetaData, create_engine
metadata = MetaData()
users = Table(
'users', metadata,
Column('id', Integer, primary_key=True),
)
articles = Table(
'articles', metadata,
Column('id', Integer, primary_key=True),
Column('user_id', Integer, ForeignKey('users.id', name='fk_articles_user_id')),
)
engine = create_engine('sqlite:///:memory:', echo=True)
metadata.create_all(engine)
Итоговый SQL запрос:
CREATE TABLE articles (
id INTEGER NOT NULL,
user_id INTEGER,
PRIMARY KEY (id),
CONSTRAINT fk_articles_user_id FOREIGN KEY(user_id) REFERENCES users (id)
)
Смотрите также
-
класс
ForeignKey,
который представляет внешний ключ -
атрибут
column,
который хранит целевой столбец внешнего ключа -
атрибут
ondelete,
который задает действие при удалении связанной строки -
атрибут
onupdate,
который задает действие при обновлении связанной строки