Как я могу заказать с помощью пользовательской функции в SQLAlchemy - PullRequest
0 голосов
/ 09 декабря 2018

Итак, у меня есть модель SQLALchemy, как показано ниже

from sqlalchemy import (create_engine, Column, BigInteger, String, 
                        DateTime)
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.ext.hybrid import hybrid_property

Base = declarative_base()

class Trades(Base):

    __tablename__ = 'trades'

    row_id = Column(BigInteger, primary_key=True, autoincrement=True)
    order_id = Column(String)
    time = Column(DateTime)
    event_type = Column(String)

    @hybrid_property
    def event_type_to_integer(self):
        return dict(received=0, open=1, done=2)[self.event_type]

    @event_type_to_integer.expression
    def event_type_to_integer(self):
        pass

Я хочу иметь возможность сначала упорядочить запрос по time, а затем по event_type.Упорядочить по времени достаточно просто, так как даты имеют естественный порядок.Однако упорядочить по event_type немного сложно, поскольку event_type может принимать значения received, open и done.Я хочу, чтобы все мои запросы упорядочивали запросы по event_type в указанном выше порядке.Кажется, мне нужно использовать гибридные свойства, которые я начал делать выше, но чтобы заставить работать функцию order_by, мне, кажется, также нужно написать функцию

    @event_type_to_integer.expression
    def event_type_to_integer(self):
        pass

.Это где я рисую бланк.Кто-нибудь есть совет о том, как написать эту функцию, чтобы сделать выше.Я попытался прочитать документацию и подобные сообщения StackOverflow.Все еще возникают проблемы.Для справки.Вот запрос, который я пытаюсь получить

    sess = Session()

    orders = (
        sess
        .query(Trades)
        .order_by(Trades.time.asc(), Trades.event_type_to_integer.asc())
        .all()
        )

    sess.close()

Выдает

KeyError: <sqlalchemy.orm.attributes.InstrumentedAttribute object at 0x7fcb11861048>

1 Ответ

0 голосов
/ 10 декабря 2018

Вы можете реализовать свой поиск с помощью выражения CASE в SQL:

from sqlalchemy import case

_event_type_lookup = dict(received=0, open=1, done=2)

class Trades(Base):
    ...
    @hybrid_property
    def event_type_to_integer(self):
        return _event_type_lookup[self.event_type]

    @event_type_to_integer.expression
    def event_type_to_integer(cls):
        return case(_event_type_lookup, value=cls.event_type)

При этом используется value сокращение .case() конструкция для создания выражения, которое сравнивает данное выражение столбца с ключами, переданными в словаре, в результате чего отображаются сопоставленные значения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...