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 [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/sqlalchemy?hl=en
-~----------~----~----~----~------~----~------~--~---