Метод update_expression класса hybrid_property
Метод update_expression класса hybrid_property
задает SQL-выражение, которое будет использоваться
при обновлении значения гибридного свойства через
UPDATE-запрос. Метод принимает функцию, возвращающую
SQL-выражение, и применяется как декоратор поверх
другой функции с тем же именем, что и у гибридного
свойства. Это позволяет отдельно определить логику
на Python-уровне (для объектов в памяти) и на
SQL-уровне (для запросов к базе данных).
Синтаксис
@hybrid_property
def name(self):
...
@name.update_expression
def name(cls):
...
Пример
Давайте создадим модель Article с гибридным
свойством full_title, которое объединяет
название и статус, и определим для него выражение
обновления:
from sqlalchemy import create_engine, String
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, Session
from sqlalchemy.ext.hybrid import hybrid_property
class Base(DeclarativeBase):
pass
class Article(Base):
__tablename__ = 'articles'
id: Mapped[int] = mapped_column(primary_key=True)
title: Mapped[str] = mapped_column(String)
status: Mapped[str] = mapped_column(String)
@hybrid_property
def full_title(self):
return f'{self.title} [{self.status}]'
@full_title.update_expression
def full_title(cls):
return cls.title + ' [' + cls.status + ']'
engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
with Session(engine) as session:
article = Article(title='article', status='draft')
session.add(article)
session.commit()
article.title = 'article updated'
session.commit()
session.refresh(article)
print(article.full_title)
Результат выполнения кода:
"article updated [draft]"
Пример
Давайте выполним массовое обновление статуса через
UPDATE-запрос, в котором используется SQL-выражение
из update_expression:
from sqlalchemy import create_engine, String, update
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, Session
from sqlalchemy.ext.hybrid import hybrid_property
class Base(DeclarativeBase):
pass
class Article(Base):
__tablename__ = 'articles'
id: Mapped[int] = mapped_column(primary_key=True)
title: Mapped[str] = mapped_column(String)
status: Mapped[str] = mapped_column(String)
@hybrid_property
def full_title(self):
return f'{self.title} [{self.status}]'
@full_title.update_expression
def full_title(cls):
return cls.title + ' [' + cls.status + ']'
engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
with Session(engine) as session:
session.add_all([
Article(title='article', status='draft'),
Article(title='user', status='draft'),
])
session.commit()
stmt = (
update(Article)
.values(status='published')
)
session.execute(stmt)
session.commit()
for article in session.query(Article).all():
print(article.full_title)
Результат выполнения кода:
"article [published]"
"user [published]"
Смотрите также
-
класс
hybrid_property,
который создает гибридное свойство модели -
метод
expression,
который задает SQL-выражение для выборки -
метод
getter,
который переопределяет Python-геттер свойства -
метод
setter,
который переопределяет Python-сеттер свойства