Python 如何在SQLAlchemy中通过自定义函数进行排序

Python 如何在SQLAlchemy中通过自定义函数进行排序,python,postgresql,sqlalchemy,Python,Postgresql,Sqlalchemy,所以我有一个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 = declarativ

所以我有一个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
我希望能够先按
时间
然后按
事件类型
排序查询。按时间排序很容易,因为日期时间有一个自然的顺序。但是,按
事件类型
排序有点棘手,因为
事件类型
可以获取值
接收的
打开的
,和
完成的
。我希望我的所有查询按
event\u type
按上述指定顺序对查询进行排序。似乎我需要使用混合属性,这是我在上面开始做的,但是要让
order\u 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>
键错误:

您可以使用SQL中的


它使用构造的简写来生成一个表达式,该表达式将给定的列表达式与字典中传递的键进行比较,生成映射值作为结果。

也许我有点误解,但您不能按
事件类型
列降序排序,因为您希望值按逆字母顺序排列吗?换句话说,
session.query(Trades).order\u by(Trades.time.asc(),Trades.event\u type.desc()).all()
对你不起作用,有什么原因吗?@benvc是的,我想这是一个解决办法。我会把它描述为一个有点黑客行为,因为它利用了一个巧合的属性,而不是数据的底层逻辑的代表。我希望能找到更强壮的东西。
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)