2014-04-30 26 views
2

我有来自外部postgresql数据库的ID列表。如何通过列表在sqlalchemy中订购数据

A = [1,2,3,4,5,6,7,98,0] 

我会做查询使用SQLAlchemy的数据库,但我会被名单PostgreSQL里的数据进行排序。

我已经阅读了很多文档,但找不到任何建议如何做到这一点。

所以,最终我将有:

results = session.query(user).limit(20).offset(10).order_by(A) 

干杯

UPDATE:

我找到的解决方案,它是如我所料不那么好,但效果很好。无论如何,如果你知道更好的解决方案,只需告诉我!

ids = ','.join([str(i) for i in A]) 
results = session.query(user).filter(user.id.in_(A)).\ 
limit(20).offset(10).\ 
order_by(" position(CONCAT(',',users.id::text,',') in ',{0},'.format(ids)") 
+0

BTW。我知道postgresql支持“连接值”http://stackoverflow.com/questions/866465/sql-order-by-the-in-value-list,但无法弄清楚如何实现这与sqlalchemy – Estatic

+0

我很好奇这种排序的原因,你会介意更多的阐述吗? – van

回答

0

另一种方法是创建一个包含每个user.id顺序位置的另一种辅助表,加入它,顺序为:

A = [1,2,3,4,5,6,7,98,0] 
stmt = " UNION ALL ".join('SELECT {0} AS user_id, {1} AS order_id'.format(uid, row) 
     for row, uid in enumerate(A)) 
ordq = text(stmt).columns(user_id=Integer, order_id=Integer).alias("t") 
results = session.query(user).join(ordq, user.id == ordq.c.user_id).order_by(ordq.c.order_id).all() 

我无法判断这是否是好于您的版本,但它至少应该是非RDBMS特定的。

+0

嗯,我的确在想这种方式,但可能它应该非常慢,因为您必须在数据库中再做一次操作,而再多一次连接而不是一次查询。 – Estatic

+0

不需要在数据库中进行操作,因为您在内存中执行此操作(如代码所示)。会不会很慢 - 非常依赖于这个选择语句的长度。 – van

+0

明白了,谢谢! – Estatic

1

如果您不一定需要在SQL中执行此操作,则可以直接在python中对返回的对象列表进行排序。

(使用python的sorted功能)

results = session.query(user).filter(user.id.in_(A)).all() 
results = sorted(results, key=lambda o: A.index(o.id)) 
-1

你可以试试:

results = session.query(user).limit(20).offset(10).order_by(*A)