Метод setter класса hybrid_property
Метод setter класса hybrid_property
определяет функцию-сеттер для гибридного
свойства. Гибридное свойство работает и на
уровне экземпляра Python-объекта, и на
уровне SQL-выражения. Метод setter
принимает функцию, которая будет вызвана
при присваивании значения атрибуту
экземпляра. Функция-сеттер получает два
аргумента: сам экземпляр и новое значение.
Синтаксис
@hybrid_property
def name(self):
...
@name.setter
def name(self, value):
...
Пример
Давайте создадим модель Article с
гибридным свойством full_title,
которое объединяет заголовок и текст, и
определим для него сеттер:
from sqlalchemy import create_engine, String, Text
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(50))
text: Mapped[str] = mapped_column(Text)
@hybrid_property
def full_title(self):
return f"{self.title}: {self.text}"
@full_title.setter
def full_title(self, value):
self.title, self.text = value.split(': ', 1)
engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
with Session(engine) as session:
article = Article()
article.full_title = 'article: some text'
session.add(article)
session.commit()
print(article.title)
print(article.text)
print(article.full_title)
Результат выполнения кода:
"article"
"some text"
"article: some text"
Пример
Давайте создадим гибридное свойство
num_status, которое объединяет
числовой код и статус, а сеттер будет
разбирать переданную строку:
from sqlalchemy import create_engine, String, Integer
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)
status: Mapped[str] = mapped_column(String(30))
num: Mapped[int] = mapped_column(Integer)
@hybrid_property
def num_status(self):
return f"{self.num}-{self.status}"
@num_status.setter
def num_status(self, value):
num, status = value.split('-', 1)
self.num = int(num)
self.status = status
engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
with Session(engine) as session:
article = Article()
article.num_status = '1-article'
session.add(article)
session.commit()
print(article.num)
print(article.status)
print(article.num_status)
Результат выполнения кода:
"1"
"article"
"1-article"
Пример
Давайте проверим, что сеттер гибридного свойства работает и при обновлении уже существующей записи:
from sqlalchemy import create_engine, String, Text, select
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(50))
text: Mapped[str] = mapped_column(Text)
@hybrid_property
def full_title(self):
return f"{self.title}: {self.text}"
@full_title.setter
def full_title(self, value):
self.title, self.text = value.split(': ', 1)
engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
with Session(engine) as session:
article = Article(full_title='article: some text')
session.add(article)
session.commit()
article.full_title = 'user: new text'
session.commit()
res = session.scalars(select(Article)).one()
print(res.title)
print(res.text)
Результат выполнения кода:
"user"
"new text"
Смотрите также
-
класс
hybrid_property,
который создает гибридное свойство -
метод
getter,
который определяет функцию-геттер -
метод
expression,
который задает SQL-выражение свойства -
метод
update_expression,
который задает SQL-выражение для обновления