指定枚举字段类型的排序顺序

Jon*_*Jon 5 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'))
Run Code Online (Sandbox Code Playgroud)

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

high
low
medium
Run Code Online (Sandbox Code Playgroud)

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

πόδ*_*κύς 6

可能存在另一种方法,但我所知道的最简单(且与数据库无关)的解决方案是在子句中使用case语句order by

首先whens通过获取用于创建列的元组来为 case 语句设置dict 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
Run Code Online (Sandbox Code Playgroud)

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

whens = {'low': 0, 'medium': 1, 'high': 2}
Run Code Online (Sandbox Code Playgroud)

其次,在 case 语句中设置排序逻辑:

sort_logic = case(value=Task.priority, whens=whens).label("priority")
Run Code Online (Sandbox Code Playgroud)

第三,运行您的查询并按您的 case 语句排序:

q = session.query(Task).order_by(sort_logic)  # see the sql at the end of this answer
Run Code Online (Sandbox Code Playgroud)

您现在有一个按原始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
Run Code Online (Sandbox Code Playgroud)

仅供参考,上述查询生成以下 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
Run Code Online (Sandbox Code Playgroud)