4

I have one parent table which holds the primary keys of several child tables. The number of child tables can be arbitrary at run time. Using SQLalchemy core, how can I join multiple child tables to this parent?

Say I have tables of class sqlalchemy.schema.Table with valid FK constraint; how do I construct this query?

I've tried i.e.;

childJoins= [sa.join(parentTable,childTables[0]),sa.join(parentTable,childTables[1])]
# childTables is a list() of Table objects who are guaranteed linked by pk 

qry = sa.select(["*"],from_obj=childJoins)

Which gives;

SELECT * 
FROM 
parentTable JOIN child1 ON child1.P_id = parentTable.C1_Id, 
parentTable JOIN child2  ON child2.P__id = parentTable.C2_Id

So parentTable is listed twice...

Tried many more variations using join() etc. looked at docs, but I still can't get what I want;

SELECT *
FROM parentTable
JOIN child1 ON parentTable.C1_Id=child1.P_Id
JOIN child2 ON parentTable.C2_Id=child2.P_Id 
...
JOIN childN ON parentTable.CN_Id=childN.P_Id

2 Answers 2

10

Simply chain the joins:

childJoins = parentTable
for child in childTables:
    childJoins = childJoins.join(child)

query = sa.select(['*'], from_obj=childJoins)
Sign up to request clarification or add additional context in comments.

Comments

0

My solution on multiple table join, inspired by Audrius Kažukauskas's solution above, using SQLAlchemy core:

from sqlalchemy.sql.expression import Select, ColumnClause

select = Select(for_update=for_update)
if self.columns:              # a list of ColumnClause objects
    for c in self.columns:
       select.append_column(c)

# table:  sqlalchemy Table type, the primary table to join to
for (join_type,left,right,left_col,right_col) in self.joins:
    isouter = join_type in ('left', 'left_outer', 'outer')
    onclause = (left.left_column == right.right_column)
    # chain the join tables
    table = table.join(right, onclause=onclause, isouter=isouter)

# if no joins, 'select .. from table where ..'
# if has joins, 'select .. from table join .. on .. join .. on .. where ..
select.append_from(table)

if self.where_clauses:
    select.append_whereclause(and_(*self.where_clauses))
...

Comments

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.