Класс Computed
Класс Computed создает вычисляемый столбец
на стороне базы данных. Значение такого столбца
не задается приложением, а рассчитывается СУБД
автоматически по заданному SQL-выражению.
Первым параметром класс принимает SQL-выражение,
например, строку с формулой. Вторым необязательным
параметром persisted можно указать, нужно ли
сохранять вычисленное значение физически в таблице.
Синтаксис
Computed(sqltext, [persisted])
Пример
Давайте создадим таблицу с вычисляемым столбцом, который складывает два числа:
from sqlalchemy import create_engine, Computed, Integer
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
engine = create_engine('sqlite:///:memory:')
class Base(DeclarativeBase):
pass
class Article(Base):
__tablename__ = 'articles'
id: Mapped[int] = mapped_column(primary_key=True)
title: Mapped[str]
num: Mapped[int]
total: Mapped[int] = mapped_column(
Computed('num + 10')
)
Base.metadata.create_all(engine)
print(Article.__table__)
Результат выполнения кода:
"Table('articles', MetaData(), Column('id', Integer(), table=<articles>, primary_key=True, nullable=False), Column('title', String(), table=<articles>, nullable=False), Column('num', Integer(), table=<articles>, nullable=False), Column('total', Integer(), Computed('num + 10'), table=<articles>), schema=None)"
Пример
Давайте вставим запись и посмотрим, как база сама рассчитает значение вычисляемого столбца:
from sqlalchemy import create_engine, Computed, Integer, select
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, Session
engine = create_engine('sqlite:///:memory:')
class Base(DeclarativeBase):
pass
class Article(Base):
__tablename__ = 'articles'
id: Mapped[int] = mapped_column(primary_key=True)
title: Mapped[str]
num: Mapped[int]
total: Mapped[int] = mapped_column(
Computed('num + 10')
)
Base.metadata.create_all(engine)
with Session(engine) as session:
article = Article(title='article', num=5)
session.add(article)
session.commit()
res = session.execute(select(Article.total)).scalar()
print(res)
Результат выполнения кода:
15
Пример
Давайте используем параметр persisted,
чтобы значение сохранялось в таблице физически:
from sqlalchemy import create_engine, Computed, Integer, select
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, Session
engine = create_engine('sqlite:///:memory:')
class Base(DeclarativeBase):
pass
class Article(Base):
__tablename__ = 'articles'
id: Mapped[int] = mapped_column(primary_key=True)
title: Mapped[str]
num: Mapped[int]
total: Mapped[int] = mapped_column(
Computed('num * 2', persisted=True)
)
Base.metadata.create_all(engine)
with Session(engine) as session:
article = Article(title='article', num=7)
session.add(article)
session.commit()
res = session.execute(select(Article.total)).scalar()
print(res)
Результат выполнения кода:
14
Итоговый SQL запрос:
CREATE TABLE articles (
id INTEGER NOT NULL,
title VARCHAR NOT NULL,
num INTEGER NOT NULL,
total INTEGER GENERATED ALWAYS AS (num * 2) STORED,
PRIMARY KEY (id)
)
Смотрите также
-
класс
Identity,
который создает автоинкрементный столбец -
класс
FetchedValue,
который представляет значение, получаемое от базы -
класс
CheckConstraint,
который задает условие проверки значений -
класс
PrimaryKeyConstraint,
который задает первичный ключ таблицы