Функция composite
Функция composite создает составное
свойство модели. Она позволяет объединить
несколько колонок таблицы в один
Python-объект, который удобно использовать
в коде. Первым параметром передается класс,
описывающий составное значение, далее
указываются колонки, из которых оно
собирается. Для каждой колонки можно задать
имя атрибута через именованный аргумент.
Синтаксис
composite(class_, *cols, **kwargs)
Пример
Давайте создадим модель с составным свойством, которое объединяет две колонки в один объект:
from sqlalchemy import create_engine, String
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, composite
class Base(DeclarativeBase):
pass
class Point:
def __init__(self, num, title):
self.num = num
self.title = title
def __repr__(self):
return f'Point(num={self.num}, title={self.title})'
class Article(Base):
__tablename__ = 'articles'
id: Mapped[int] = mapped_column(primary_key=True)
num: Mapped[int]
title: Mapped[str] = mapped_column(String(100))
point = composite(Point, num, title)
engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
from sqlalchemy.orm import Session
with Session(engine) as session:
article = Article(id=1, point=Point(num=10, title='article'))
session.add(article)
session.commit()
res = session.get(Article, 1)
print(res.point)
Результат выполнения кода:
Point(num=10, title=article)
Пример
Давайте зададим явные имена атрибутов для колонок через именованные аргументы:
<+python+>
from sqlalchemy import create_engine, String
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, composite
class Base(DeclarativeBase):
pass
class ArticleInfo:
def __init__(self, num, title, status):
self.num = num
self.title = title
self.status = status
def __repr__(self):
return f'ArticleInfo(num={self.num}, title={self.title}, status={self.status})'
class Article(Base):
__tablename__ = 'articles'
id: Mapped[int] = mapped_column(primary_key=True)
num: Mapped[int]
title: Mapped[str] = mapped_column(String(100))
status: Mapped[str] = mapped_column(String(50))
info = composite(ArticleInfo, num, title, status)
engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
from sqlalchemy.orm import Session
with Session(engine) as session:
article = Article(
id=1,
info=ArticleInfo(num=5, title='article', status='draft')
)
session.add(article)
session.commit()
res = session.get(Article, 1)
print(res.info.title)
print(res.info.status)
<-python+>
Результат выполнения кода:
"article"
"draft"
Пример
Давайте изменим составное свойство и сохраним изменения в базу данных:
from sqlalchemy import create_engine, String
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, composite, Session
class Base(DeclarativeBase):
pass
class Point:
def __init__(self, num, title):
self.num = num
self.title = title
def __composite_values__(self):
return self.num, self.title
def __repr__(self):
return f'Point(num={self.num}, title={self.title})'
class Article(Base):
__tablename__ = 'articles'
id: Mapped[int] = mapped_column(primary_key=True)
num: Mapped[int]
title: Mapped[str] = mapped_column(String(100))
point = composite(Point, num, title)
engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
with Session(engine) as session:
article = Article(id=1, point=Point(num=1, title='article'))
session.add(article)
session.commit()
article.point = Point(num=2, title='user')
session.commit()
res = session.get(Article, 1)
print(res.num)
print(res.title)
Результат выполнения кода:
2
"user"
Смотрите также
-
функцию
column_property,
которая создает вычисляемое свойство модели -
функцию
synonym,
которая создает синоним для атрибута модели -
функцию
mapped_column,
которая описывает колонку в декларативной модели -
класс
Mapped,
который указывает тип атрибута модели