モデル定義で外部キー定義する場合は、こんな感じで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すごく便利。