Life is Really Short, Have Your Life!!

ござ先輩の主に技術的なメモ

SQLAlchemyの結合条件の制御

モデル定義で外部キー定義する場合は、こんな感じでJOINできる。Flask-SQLAlchemyの場合です。

Order.query.join(OrderDetail, Customer, Destination, Item)

こんな感じのSQLが生成される。

FROM orders 
INNER JOIN order_detail ON order.id = order_detail.order_id 
INNER JOIN customer ON customer.id = order.customer_id
INNER JOIN destination ON destination.customer_id = customer.id 
INNER JOIN items ON item.id = order_detail.item_id 

今回はこのCustomerが曲者です。

CustomerはOrderの外部キーでもあるし、Destinationの外部キーでもあるという構成なので、この書き方をしてしまうと結合順が優先されて、顧客と納品先が結合されます。そうすると、顧客に対して納品先がN件ある場合、注文明細がN倍に膨れ上がって表示されてしまいます。

どうするかというと、結合条件をJOIN関数の第2引数にくれてやります。

Order.query.join(Customer, OrderDetail, Item).\
join(Destination, Destination.id == Order.destination_id)

こういうSQLに変わりました。

FROM orders 
INNER JOIN order_detail ON order.id = order_detail.order_id 
INNER JOIN customer ON customer.id = order.customer_id
INNER JOIN items ON item.id = order_detail.item_id 
INNER JOIN destination ON destination_id = Order.id 

はー、まじでAlchemyすごく便利。