I have a model that uses the Enum
field type:
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'))
If I sort the records by priority (the Enum), it's sorts alphabetically:
high
low
medium
How can I specify the sort-order for this field?
We can use the natural sort order or sort by their properties. Any Enum type we create implements the Comparable interface. Below is an excerpt from the Java documentation. Enum<E> implements Comparable<E> via the natural order of the enum (the order in which the values are declared).
The order in which the enumeration values are given matters.
An ENUM is a string object with a value chosen from a list of permitted values that are enumerated explicitly in the column specification at table creation time.
Enumeration or Enum in C is a special kind of data type defined by the user. It consists of constant integrals or integers that are given names by a user. The use of enum in C to name the integer values makes the entire program easy to learn, understand, and maintain by the same or even different programmer.
Another way may exist, but the simplest (and most database-agnostic) solution I know of would be to use a case
statement in the order by
clause.
First, set up your whens
dict for your case statement by getting the tuple you used to create the column's 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
Or, if you must, hard code your whens
dict (definitely less than ideal, since you now have to change code in two places):
whens = {'low': 0, 'medium': 1, 'high': 2}
Second, set up your sort logic in a case statement:
sort_logic = case(value=Task.priority, whens=whens).label("priority")
Third, run your query and order by your case statement:
q = session.query(Task).order_by(sort_logic) # see the sql at the end of this answer
You now have a query sorted by your original Enum
tuple:
>>> 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
Just for reference, the above query produces the following 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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With