指定Enum字段类型的排序顺序

时间:2014-05-12 17:09:58

标签: python sqlalchemy

我有一个使用Enum字段类型的模型:

from sqlalchemy import Column, Enum, Integer, String

class Task(Base):
    __tablename__ = 'tasks'

    id = Column(Integer, primary_key=True)
    summary = Column(String)
    priority = Column(Enum('low', 'medium', 'high'))

如果按优先级(Enum)对记录进行排序,则按字母顺序排序:

high
low
medium

如何指定此字段的排序顺序?

1 个答案:

答案 0 :(得分:4)

可能存在另一种方式,但我所知道的最简单(也是大多数数据库不可知)的解决方案是在order by子句中使用case statement

首先,为您的案例陈述设置whens dict,方法是获取用于创建列{c} Enum的元组:

enums = Task.priority.type.enums  # finds the Enum tuple (with the same order you originally gave it)
whens = {priority: index for index, priority in enumerate(enums)}  # dynamically creates whens dict based on the order of the Enum tuple

或者,如果必须的话,硬编码你的whens字典(绝对不太理想,因为你现在必须在两个地方更改代码):

whens = {'low': 0, 'medium': 1, 'high': 2}

第二次,在案例陈述中设置排序逻辑:

sort_logic = case(value=Task.priority, whens=whens).label("priority")

第三次,按您的案例陈述运行您的查询和订单:

q = session.query(Task).order_by(sort_logic)  # see the sql at the end of this answer

您现在有一个按原始Enum元组排序的查询:

>>> for item in q:
        print item.id, item.priority
#  now in the order you were looking for
4 low
7 low
3 medium
8 medium
2 high
6 high

仅供参考,上述查询产生以下SQL:

SELECT        tasks.id AS tasks_id,
              tasks.summary AS tasks_summary,
              tasks.priority AS tasks_priority 
FROM          tasks
ORDER BY CASE tasks.priority
             WHEN :param_1 THEN :param_2
             WHEN :param_3 THEN :param_4
             WHEN :param_5 THEN :param_6
         END