Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In sqlalchemy, how can I combine two queries by having a column entry identical?

Suppose I have a mapped class User, mapped to a tables of the same name, and a column "age" for his age. I'm now interested in the following problem:

In the course of my application, there emerge two queries:

q1 = session.query(User).filter(lots of conditions)
q2 = session.query(User).filter(lots of other conditions)

I now want to "join" q2 onto q1 upon the condition that they have the same age. But I have no idea of how this might work. I tried the following without success:

q1.join(q2.subquery(), q1.age==q2.age) # the query doesn't hold the columns of the queried class
q1.join(Age).join(q2.subquery()) # Works only if age is a relationship with mapped class Age

My closest calls were something like this:

a1 = aliased(User)
a2 = aliased(User)
q1 = session.query(a1)
q2 = session.query(a2)
s = q2.subquery()
q1.join(s, a1.age==a2.age).all()
>>> sqlalchemy.exc.OperationalError: (OperationalError) no such column: user_2.age 'SELECT user_1.id AS user_1_id, user_1.name AS user_1_name, user_1.age AS user_1_age \nFROM user AS user_1 JOIN (SELECT user_2.id AS id, user_2.name AS name, user_2.age AS age \nFROM user AS user_2) AS anon_1 ON user_1.age = user_2.age' ()

Any ideas about how to make this run?

like image 393
Turion Avatar asked Nov 21 '12 17:11

Turion


People also ask

What is session merge in SQLAlchemy?

The SQLAlchemy documentation says "session. merge() reconciles the current state of an instance and its associated children with existing data in the database".

What does all () do in SQLAlchemy?

all() method. The Query object, when asked to return full entities, will deduplicate entries based on primary key, meaning if the same primary key value would appear in the results more than once, only one object of that primary key would be present.

What is join in SQLAlchemy?

Python Flask and SQLAlchemy ORM The join() method returns a join object from one table object to another. join(right, onclause = None, isouter = False, full = False) The functions of the parameters mentioned in the above code are as follows − right − the right side of the join; this is any Table object.


1 Answers

After fiddling around and reading answers to questions about subqueries, I managed to find a solution. Instead of the last, offending line, put:

q1.join(s, a1.age==s.columns.age).all()

That way, the on-clause becomes ON user_1.age = anon_1.age, which is what we want.

like image 123
Turion Avatar answered Oct 14 '22 00:10

Turion