Класс hybrid_property
Класс hybrid_property создает гибридное
свойство модели. Такое свойство доступно как
обычный Python-атрибут у экземпляра объекта
и одновременно транслируется в SQL-выражение
при обращении к нему на уровне класса. Первым
параметром передается функция-геттер, которая
вычисляет значение для экземпляра. Дополнительно
можно определить сеттер методом setter,
делитер методом deleter и SQL-выражение
методом expression.
Синтаксис
from sqlalchemy.ext.hybrid import hybrid_property
class Model(Base):
@hybrid_property
def name(self):
return self._name
Пример
Давайте создадим модель Article с
гибридным свойством title_upper,
которое возвращает заголовок в верхнем регистре:
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(100))
text: Mapped[str] = mapped_column(String(500))
status: Mapped[str] = mapped_column(String(50))
num: Mapped[int]
@hybrid_property
def title_upper(self):
return self.title.upper()
engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
with Session(engine) as session:
article = Article(
title='article',
text='some text',
status='draft',
num=1
)
session.add(article)
session.commit()
print(article.title_upper)
Результат выполнения кода:
"ARTICLE"
Пример
Гибридное свойство можно использовать прямо
в SQL-запросе на уровне класса. Для этого
определим SQL-выражение через метод
expression:
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(String(100))
text: Mapped[str] = mapped_column(String(500))
status: Mapped[str] = mapped_column(String(50))
num: Mapped[int]
@hybrid_property
def title_upper(self):
return self.title.upper()
@title_upper.expression
def title_upper(cls):
return cls.title.op('upper')()
engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
with Session(engine) as session:
session.add_all([
Article(title='article', text='text one', status='draft', num=1),
Article(title='user', text='text two', status='published', num=2),
])
session.commit()
stmt = select(Article).where(Article.title_upper == 'ARTICLE')
res = session.scalars(stmt).all()
for article in res:
print(article.title)
Итоговый SQL запрос:
SELECT articles.id, articles.title, articles.text, articles.status, articles.num
FROM articles
WHERE upper(articles.title) = ?
Результат выполнения кода:
article
Пример
Определим сеттер через метод setter,
чтобы можно было присваивать значение
гибридному свойству:
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(100))
text: Mapped[str] = mapped_column(String(500))
status: Mapped[str] = mapped_column(String(50))
num: Mapped[int]
@hybrid_property
def title_upper(self):
return self.title.upper()
@title_upper.setter
def title_upper(self, value):
self.title = value.lower()
engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
with Session(engine) as session:
article = Article(
title='article',
text='some text',
status='draft',
num=1
)
session.add(article)
session.commit()
article.title_upper = 'NEW TITLE'
session.commit()
print(article.title)
print(article.title_upper)
Результат выполнения кода:
new title
NEW TITLE
Смотрите также
-
класс
hybrid_property,
который создает гибридное свойство модели -
метод
getter,
который определяет функцию-геттер свойства -
метод
setter,
который определяет функцию-сеттер свойства -
метод
expression,
который задает SQL-выражение для уровня класса