在sqlalchemy中使用PostgreSQL聚合ORDER BY
我有一个查询,使用的是PostgreSQL的语法,在聚合函数中使用ORDER BY,类似这样的:
SELECT some_agg_func(a ORDER BY b DESC) FROM table;
有没有人知道怎么用sqlalchemy表达语言来实现这个功能?
3 个回答
1
你需要使用SQLAlchemy的编译器扩展来实现这个功能。下面是一个关于Postgres的string_agg
函数的例子:
from sqlalchemy.sql.expression import ColumnElement, _literal_as_column
from sqlalchemy.dialects import postgresql
from sqlalchemy.ext.compiler import compiles
class string_agg(ColumnElement):
def __init__(self, expr, separator, order_by=None):
self.type = Text()
self.expr = _literal_as_column(expr)
self.separator = literal(separator)
self.order_by = _literal_as_column(order_by)
@property
def _from_objects(self):
return self.expr._from_objects
@compiles(string_agg, 'postgresql')
def compile_string_agg(element, compiler, **kwargs):
head = 'string_agg(%s, %s' % (
compiler.process(element.expr),
compiler.process(element.separator)
)
if element.order_by is not None:
tail = ' ORDER BY %s)' % compiler.process(element.order_by)
else:
tail = ')'
return head + tail
query = session.query(string_agg(Foo.bar, ', ', order_by=Foo.bar.desc()))
# Print compiled SQL query.
print query.statement.compile(dialect=postgresql.dialect())
# Run the query and print result.
print query.scalar()
6
我觉得 SqlAlchemy 1.1 现在原生支持 string_agg
这个功能了。你可以在这个链接找到相关信息:http://docs.sqlalchemy.org/en/latest/dialects/postgresql.html#sqlalchemy.dialects.postgresql.aggregate_order_by(在页面上搜索 "func.string_agg" 就能找到)
14
来自 SQLAlchemy 文档:
from sqlalchemy.dialects.postgresql import aggregate_order_by
expr = func.array_agg(aggregate_order_by(table.c.a, table.c.b.desc()))
stmt = select([expr])