AF wrote: > Hello, > > For instance if I have data tables for users, orders, and > order_line_items how would I generate a report that lists: > > 1) users, > 2) and for each user, his/her orders, > 3) and for each order, all the order_line_items > > I guess I could do it in a loop in python, but I wonder of there is a > better way using SQLAlchemy. > > Thank you, > :) > I'm assuming you already have classes and mappers set up for your users, orders, and order line items, with ORM relations set up for User->Order and Order->OrderLineItem relations.
Looping in python is your best bet for formatting the report, but you have some options regarding how to get the data from the database: 1. Lazy loading (default SQLAlchemy behavior): SQLAlchemy will query the database the first time you access each user's orders and each order's line items. This may end up sending a lot of queries to the database, which may hurt performance, but it is easy and minimizes the amount of redundant data sent from the database server to your client. ex: q = session.query(User) for user in q: # not shown: output user data # Each iteration of this for loop causes an SQL query for order in user.orders: # not shown: output order data # Each iteration of this for loop causes an SQL query for line_item in order.line_items: # not shown: output line item data pass 2. Eager loading: SQLAlchemy issues one SQL query with OUTER JOINs to get all your data. This is probably your best bet, but can include many duplicate cells for your users and orders. I would only worry about this if you are worried about bandwidth between your client and database server. ex: q = session.query(User).options(eagerload_all("orders.line_items")) # or, if you need to filter/order by orders and/or line items: q = (session.query(User) .outerjoin(User.orders) .options(contains_eager("orders")) .outerjoin(Order.line_items) .options(contains_eager("orders.line_items")) .order_by(Order.date)) # Only one SQL query is sent when we start iterating over q. for user in q: # not shown: output user data for order in user.orders: # not shown: output order data for line_item in order.line_items: # not shown: output line item data pass 3. Batch fetching: You send one SQL query to fetch all the users, one SQL query to fetch all the orders, and one SQL query to fetch all the order line items. SQLAlchemy does not have any built-in support for this, so you have to generate the queries yourself and relate the results yourself. However, it does give you the no-redundant-cells advantage of lazy loading with just 3 queries. The concept is described here: http://groups.google.com/group/sqlalchemy/browse_thread/thread/bc74259b45397f69 Hope it helps, -Conor --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To post to this group, send email to sqlalchemy@googlegroups.com To unsubscribe from this group, send email to sqlalchemy+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~----------~----~----~----~------~----~------~--~---