Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python SQLAlchemy Query using labeled OVER clause with ORM

This other question says how to use the OVER clause on sqlalchemy:

Using the OVER window function in SQLAlchemy

But how to do that using ORM? I have something like:

q = self.session.query(self.entity, func.count().over().label('count_over'))

This fails when I call q.all() with the following message:

sqlalchemy.exc.InvalidRequestError:
Ambiguous column name 'count(*) OVER ()' in result set! try 'use_labels' option on select statement

How can I solve this?

like image 832
user1538560 Avatar asked Dec 16 '14 17:12

user1538560


People also ask

How does the querying work with SQLAlchemy?

All SELECT statements generated by SQLAlchemy ORM are constructed by Query object. It provides a generative interface, hence successive calls return a new Query object, a copy of the former with additional criteria and options associated with it.

Should I use SQLAlchemy core or ORM?

If you want to view your data in a more schema-centric view (as used in SQL), use Core. If you have data for which business objects are not needed, use Core. If you view your data as business objects, use ORM. If you are building a quick prototype, use ORM.

Is SQLAlchemy better than Django ORM?

4) Applications In addition to this, since it interacts directly with the database, you can simply run the queries against the database without actually using the ORM. Plus, SQLAlchemy is much more powerful than Django, albeit with a little higher learning curve.

What is scalar subquery SQLAlchemy?

A scalar subquery is a subquery that selects only one column or expression and returns one row. A scalar subquery can be used anywhere in an SQL query that a column or expression can be used.


2 Answers

You have the over syntax almost correct, it should be something like this:

import sqlalchemy
q = self.session.query(
    self.entity,
    sqlalchemy.over(func.count()).label('count_over'),
)

Example from the docs:

from sqlalchemy import over
over(func.row_number(), order_by='x')
like image 69
Wolph Avatar answered Oct 07 '22 08:10

Wolph


SQLAlchemy Query object has with_entities method that can be used to customize the list of columns the query returns:

Model.query.with_entities(Model.foo, func.count().over().label('count_over'))

Resulting in following SQL:

SELECT models.foo AS models_foo, count(*) OVER () AS count_over FROM models
like image 37
plaes Avatar answered Oct 07 '22 08:10

plaes