2011-09-16 27 views
6

Estoy tratando de ordenar un objeto SQLAlchemy ORM por un campo, pero con un orden específico de los valores (que no es ni ascendente ni descendente). Si estuviera haciendo esta consulta en MySQL, se vería así;SQLAlchemy ORDER BY FIELD()

SELECT letter FROM alphabet_table WHERE letter in ('g','a','c','k') 
ORDER BY FIELDS(letter, 'g','a','c','k'); 

para la salida:

letter 
------ 
    g 
    a 
    c 
    k 

Para SQLAlchemy, he estado tratando de cosas a lo largo de las líneas de:

session.query .Filter (AlphabetTable) (AlphabetTable.letter.in_ (('g', 'a', 'c', 'k'))) order_by (AlphabetTable.letter.in _ (('g', 'a', 'c', 'k')))

¿Qué no funciona ... alguna idea? Es una pequeña lista constante de una sola vez, y podría simplemente crear una tabla con el orden y luego unirme, pero eso parece demasiado.

+0

Puede llamar a un procedimiento almacenado mysql desde sqlalchemy? – Louis

Respuesta

7

esto puede no ser una solución muy satisfactoria, pero la forma de usar un case expression en lugar de order by fields:

sqlalchemy.orm.Query(AlphabetTable) \ 
    .filter(AlphabetTable.letter.in_("gack")) \ 
    .order_by(sqlalchemy.sql.expression.case(((AlphabetTable.letter == "g", 1), 
               (AlphabetTable.letter == "a", 2), 
               (AlphabetTable.letter == "c", 3), 
               (AlphabetTable.letter == "k", 4)))) 
8

Un sqlalchemy func expression se puede utilizar para generar el order by field cláusula:

session.query(AlphabetTable) \ 
    .filter(AlphabetTable.letter.in_("gack")) \ 
    .order_by(sqlalchemy.func.field(AlphabetTable.letter, *"gack"))