Метод deleter класса hybrid_property
Метод deleter класса hybrid_property
регистрирует функцию, которая будет вызвана
при удалении значения гибридного свойства
через инструкцию del. Метод принимает
один параметр - функцию-делитер, которая
получает экземпляр класса и выполняет
необходимые действия по очистке или
удалению связанных данных.
Гибридное свойство работает и на уровне
Python-объекта, и на уровне SQL-выражения.
Метод deleter отвечает только за
Python-уровень, то есть за поведение при
вызове del instance.attr.
Синтаксис
@hybrid_property
def name(self):
return self._name
@name.deleter
def name(self):
# cleanup logic
pass
Пример
Давайте создадим модель Article с
гибридным свойством title и
определим для него делитер, который
сбрасывает значение в None:
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('title', String)
@hybrid_property
def title(self):
return self._title
@title.setter
def title(self, value):
self._title = value
@title.deleter
def title(self):
self._title = None
engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
with Session(engine) as session:
article = Article(title='article 1')
session.add(article)
session.commit()
print(article.title)
del article.title
print(article.title)
Результат выполнения кода:
"article 1"
"None"
Пример
Давайте рассмотрим более практичный
пример: при удалении гибридного свойства
status автоматически сбрасывается
связанное поле num:
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('status', String)
num: Mapped[int] = mapped_column(Integer, nullable=True)
@hybrid_property
def status(self):
return self._status
@status.setter
def status(self, value):
self._status = value
@status.deleter
def status(self):
self._status = 'deleted'
self.num = 0
engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
with Session(engine) as session:
article = Article(status='active', num=5)
session.add(article)
session.commit()
print(article.status, article.num)
del article.status
print(article.status, article.num)
Результат выполнения кода:
"active 5"
"deleted 0"
Пример
Давайте посмотрим, как делитер работает
вместе с getter и setter
в одном гибридном свойстве, и убедимся,
что удаление отражается в базе данных:
from sqlalchemy import create_engine, String, 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('title', String)
@hybrid_property
def title(self):
return self._title
@title.setter
def title(self, value):
self._title = value.upper()
@title.deleter
def title(self):
self._title = ''
engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
with Session(engine) as session:
article = Article(title='article')
session.add(article)
session.commit()
print(article.title)
del article.title
session.commit()
res = session.execute(select(Article._title)).scalar_one()
print(repr(res))
Результат выполнения кода:
"ARTICLE"
"''"
Смотрите также
-
класс
hybrid_property,
который создает гибридное свойство -
метод
getter,
который определяет поведение при чтении значения -
метод
setter,
который определяет поведение при установке значения -
метод
expression,
который задает SQL-выражение для гибридного свойства