SQLAlchemy: применить фильтр к гибридной сборке свойств из отношения - PullRequest
0 голосов
/ 04 мая 2020

У меня есть класс Item и класс ItemPrice. Item имеет много ItemPrice.

Цена Item (гибридное свойство) является самой последней ItemPrice, связанной с его идентификатором.

Вот код

class Item(db.Model):
    __tablename__ = "item"

    id_item = db.Column(db.Integer,
                        primary_key=True,
                        index=True,
                        unique=True)
    item_prices = db.relationship('ItemPrice', lazy='select', 
                                  backref('item', lazy='joined'))

    @hybrid_property
    def price(self):
        return self.item_prices[-1].price

    @price.expression
    def price(cls):
        return select([ItemPrice.price]) \
            .correlate(Item, ItemPrice) \
            .where(ItemPrice.id_item==cls.id_item) \
            .order_by(ItemPrice.created.desc()) \
            .limit(1)


class ItemPrice(db.Model):
    __tablename__ = "item_price"

    id_item_price = db.Column(db.Integer,
                              primary_key=True,
                              index=True,
                              unique=True)

    id_item = db.Column(db.Integer, ForeignKey('item.id_item'),
                        index=False,
                        nullable=False)

    created = db.Column(db.DateTime, default=db.func.current_timestamp(),
                    index=True,
                    unique=False,
                    nullable=False)

Я пытаюсь запустить фильтр для свойства price

Item.query.join(ItemPrice).filter(Item.price >= 1).all()

, и я получаю эту ошибку, которая говорит, что я не могу выполнить сравнение int с Select объектом.

TypeError: '>=' not supported between instances of 'Select' and 'int'

Вопросы

Связана ли ошибка с тем, как я написал @price.expression или filter?

Как изменить @price.expression или filter, чтобы исправить этот запрос?

1 Ответ

0 голосов
/ 05 мая 2020
@price.expression
def price(cls):
    return select([ItemPrice.price]) \
        .correlate(Item, ItemPrice) \
        .where(ItemPrice.id_item==cls.id_item) \
        .order_by(ItemPrice.created.desc()) \
        .as_scalar()

Для тех, кто пытается отладить проблему, аналогичную этой, вот как я получил ее для чего-то работающего:

  1. Я зарегистрировал запрос Item.query.join(ItemPrice).filter(Item.price >= 1).
  2. Подзапрос для поиска discount_pct возвращал список вместо одного значения.
  3. Способ возврата одного значения вместо списка - с помощью as_scalar().
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...