3

Suppose I have two classes ChildA and ChildB which both have a relationship to Parent. Suppose also that I already have two queries defined, qa and qb, which query the respective child classes. I want to join qb onto qa upon having the same parent.

If parent were just an ordinary column, I could do the following:

subquery = qb.subquery()
joined_query = qa.join(subquery, AliasedChildA.parent==subquery.columns.parent)

Here, AliasedChildA is an alias of ChildA. (I have full control over how the queries are being created, but not over the filters that are being applied to them later.) But now, since parent is a relationship, it is not contained in subquery.columns.

How can I join qa and qb upon having the same parent?

3 Answers 3

1

Try the below:

qa = session.query(ChildA)
qb = session.query(ChildB)
# @note: *qa* and *qb* may include other filters etc, 
# but assuming they do not contain joins on *Parent*
subquery = qb.subquery()
qry = qa.join(Parent).join(subquery)
Sign up to request clarification or add additional context in comments.

2 Comments

That's a nice idea. The only problem I have is that I don't know in advance which class Parent the relationship parent is being mapped on. Maybe I should look into how to gather that information by introspection. (Maybe I should try to solve easier/more natural problems...)
As long as each ChildA/B has only one relationship to Parent, it should work. Otherwise, you should know which relationship you require for the purpose of your requirement: ..upon having the same parent
1

Try it with AliasedChildA.parent_id == subquery.c.parent_id (and_ a few clauses if you have a composite pk).

4 Comments

That's the workaround I'm currently trying. However, this relies on the relationship being built upon parent_id, and usually I can't control the names of the columns, only of the relationships. Can I somehow find out which column is used to establish the relationship?
Also, at the end I would like to perform a join upon something like parent1.children == parent2.children, and I have no idea about how to do that.
You can do some introspection from orm classes (class.attribute.property.column), but you can't do it from your starting point of a subquery. Play around with an embedded IPython to see what you can introspect.
You can pass SQLAlchemy fields as arguments to your function directly. my_join_function(Model1.xxx, Model2.yyy) You can pass strings and use getattr(model, field_name) as well. I wouldn't recommend wildly introspecting things to find field names that match up. That seems like code smell.
1
query_a.subquery().join(query_b.subquery(), $on_condition...)

works for me :)

3 Comments

What's the format of $on_condition? Can you give an example, please?
@egor83 I forget it after so long time, sorry.
@egor83 something like query_a.c.col1 == query_b.c.col1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.