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

Атрибут onupdate класса ForeignKey

Атрибут onupdate класса ForeignKey задает SQL-действие, которое автоматически выполняется при обновлении значения первичного ключа в родительской таблице. Это поведение реализуется на уровне базы данных через конструкцию ON UPDATE внешнего ключа. Атрибут принимает строковые значения, такие как CASCADE, SET NULL, SET DEFAULT, RESTRICT и NO ACTION. Если атрибут не указан, база данных применяет поведение по умолчанию - обычно NO ACTION.

Синтаксис

ForeignKey('parent_table.column', onupdate='CASCADE')

Пример

Давайте создадим две связанные таблицы - users и articles - и укажем для внешнего ключа onupdate='CASCADE'. При обновлении id пользователя значение внешнего ключа в статьях обновится автоматически:

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', onupdate='CASCADE') ) engine = create_engine('sqlite:///:memory:') Base.metadata.create_all(engine) with Session(engine) as session: user = User(id=1, name='user') session.add(user) session.flush() article = Article(id=1, title='article', user_id=1) session.add(article) session.commit() user.id = 2 session.commit() print(article.user_id)

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

"2"

Пример

Давайте рассмотрим вариант с onupdate='SET NULL'. При обновлении первичного ключа родителя внешний ключ в дочерней таблице обнуляется:

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', onupdate='SET NULL'), nullable=True ) engine = create_engine('sqlite:///:memory:') Base.metadata.create_all(engine) with Session(engine) as session: user = User(id=1, name='user') session.add(user) session.flush() article = Article(id=1, title='article', user_id=1) session.add(article) session.commit() user.id = 2 session.commit() session.refresh(article) print(article.user_id)

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

"None"

Пример

Давайте посмотрим, какой SQL генерирует SQLAlchemy при создании таблицы с onupdate='CASCADE':

from sqlalchemy import create_engine, ForeignKey from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column from sqlalchemy.schema import CreateTable 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', onupdate='CASCADE') ) 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) ON UPDATE CASCADE )

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

  • класс ForeignKey,
    который представляет внешний ключ таблицы
  • атрибут ondelete,
    который задает действие при удалении родителя
  • атрибут column,
    который возвращает целевую колонку внешнего ключа
  • метод get_referent,
    который возвращает родительский объект по внешнему ключу
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить