Как в SQLAlchemy сделать модель, с колонкой которая суммирует значения?

Здравствуйте. Не могу разобраться с моделью SQLAlchemy.
Есть 2 таблицы, вот их модели.

class MaterialSupply(base):
    """Родитель"""
    __tablename__ = "material_supply"

    id = Column(Integer, primary_key=True)
    date = Column(Date, name="data", nullable=False, unique=True)
    note = Column(Text)
    positions = relationship("MaterialSupplyPosition", back_populates="supply", lazy=False, uselist=True, cascade="all, delete, delete-orphan")

class MaterialSupplyPosition(base):
   """Дети"""
    __tablename__ = "material_supplyposition"

    id = Column(Integer, primary_key=True)
    weight = Column(DECIMAL(11, 4), nullable=False)
    price = Column(DECIMAL(11, 4), nullable=False)
    supply_id = Column(Integer, ForeignKey(MaterialSupply.id), name="Material_SupplyId", nullable=False)
    supply = relationship("MaterialSupply", back_populates="positions", lazy=True, uselist=False)


Мне нужно в таблице MaterialSupply получить колонку total_weight (сумма весов всех позиций поставки "sum(material_supplyposition.weight)"), и что бы по ней можно было фильтровать. Как это сделать? Я много чего перепробовал, кое как я нашел 2 способа, но оба работают не до конца.

"""Можно для таблицы добавить колонку, но тогда запрос не группируется и превращается в одну результирующую строку"""
MaterialSupply.invited_name = column_property(func.sum(MaterialSupplyPosition.weight))

"""Второй метод работает, но мне не нравиться что задача суммирования, ложиться на сервер"""
class MaterialSupply(base):
    __tablename__ = "material_supply"

    id = Column(Integer, primary_key=True)
    date = Column(Date, name="data", nullable=False, unique=True)
    note = Column(Text)

    positions = relationship("MaterialSupplyPosition", back_populates="supply", lazy=False, uselist=True, cascade="all, delete, delete-orphan")

    @hybrid_property
    def total_weight(self):
        return sum(pos.weight for pos in self.positions)  # Получается что сумму делает сервер, уже после получения данных 

    @total_weight.expression
    def total_weight(cls):
        return select([func.sum(MaterialSupplyPosition.weight)]).\
                where(MaterialSupplyPositio
  • Вопрос задан
  • 133 просмотра
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы