SQLAlchemyでサブクエリとJOINを使ってみる

「SQLAlchemyでJOINの順番とかいじれるんだっけー?」というような話がきっかけでどうやるのか調べてた。
サブクエリもJOINも簡単に使えていいですねえ。

spam.py

from sqlalchemy import Table, Column, Integer, String, MetaData, ForeignKey
from sqlalchemy.sql import select
 
metadata = MetaData()
table1 = Table('table1', metadata,
    Column('id', Integer, primary_key=True),
    Column('name', String),
)
 
table2 = Table('table2', metadata,
    Column('id', Integer, primary_key=True),
    Column('table1_id', None, ForeignKey('table1.id')),
)
 
table3 = Table('table3', metadata,
    Column('id', Integer, primary_key=True),
    Column('table2_id', None, ForeignKey('table2.id')),
)
 
print select(
        [table1, table2, table3]
    ).select_from(
        table1.join(
            table2.join(table3)
        )
    )
 
print "----"
 
t = select([table1]).limit(100).alias('T1')
print select(
        [t, table2, table3]
    ).select_from(
        t.join(
            table2.join(table3)
        )
    )

実行結果

$ python spam.py 
SELECT table1.id, table1.name, table2.id, table2.table1_id, table3.id, table3.table2_id 
FROM table1 JOIN (table2 JOIN table3 ON table2.id = table3.table2_id) ON table1.id = table2.table1_id
----
SELECT "T1".id, "T1".name, table2.id, table2.table1_id, table3.id, table3.table2_id 
FROM (SELECT table1.id AS id, table1.name AS name 
FROM table1
 LIMIT :param_1) AS "T1" JOIN (table2 JOIN table3 ON table2.id = table3.table2_id) ON "T1".id = table2.table1_id

2014 2/22追記

aodagとshimizukawaから「aliasメソッドを使えばSessionは不要」と教えてもらったので、コードを修正しました。