为枚举字段类型指定排序顺序
我有一个模型,它使用了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 个回答
10
可能还有其他方法,但我知道最简单(而且不依赖于特定数据库)的解决方案就是在 order by
语句中使用一个 case
语句。
第一步,先为你的 case
语句准备一个 whens
字典,这个字典是通过获取你用来创建列的 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}
第二步,在 case
语句中设置你的排序逻辑:
sort_logic = case(value=Task.priority, whens=whens).label("priority")
第三步,运行你的查询,并按照你的 case
语句进行排序:
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