[Sqlalchemy-commits] sqlalchemy: - doc updates in loading
Brought to you by:
zzzeek
From: <co...@sq...> - 2011-11-24 15:47:43
|
details: http://hg.sqlalchemy.org/sqlalchemy/sqlalchemy/rev/6308834a1f31 changeset: 7919:6308834a1f31 user: zzzeek date: Thu Nov 24 10:47:10 2011 -0500 description: - doc updates in loading - de-emphasize contains_alias() which is pretty much a non-use case - add docs for immediateload which have been missing all this time - fix links, formatting diffstat: doc/build/orm/loading.rst | 30 +++++++-------------------- lib/sqlalchemy/orm/__init__.py | 45 +++++++++++++++++++++++++++++++++++++---- 2 files changed, 48 insertions(+), 27 deletions(-) diffs (146 lines): diff -r 49167171134b -r 6308834a1f31 doc/build/orm/loading.rst --- a/doc/build/orm/loading.rst Tue Nov 22 19:01:21 2011 -0500 +++ b/doc/build/orm/loading.rst Thu Nov 24 10:47:10 2011 -0500 @@ -383,8 +383,8 @@ # get results normally r = query.from_statement(statement) -It works just as well with an inline ``Query.join()`` or -``Query.outerjoin()``:: +It works just as well with an inline :meth:`.Query.join` or +:meth:`.Query.outerjoin`:: session.query(User).outerjoin(User.addresses).options(contains_eager(User.addresses)).all() @@ -410,9 +410,9 @@ FROM users LEFT OUTER JOIN email_addresses AS email_addresses_1 ON users.user_id = email_addresses_1.user_id The ``alias`` argument is used only as a source of columns to match up to the -result set. You can use it even to match up the result to arbitrary label -names in a string SQL statement, by passing a selectable() which links those -labels to the mapped :class:`~sqlalchemy.schema.Table`:: +result set. You can use it to match up the result to arbitrary label +names in a string SQL statement, by passing a :func:`.select` which links those +labels to the mapped :class:`.Table`:: # label the columns of the addresses table eager_columns = select([ @@ -428,7 +428,7 @@ "from users left outer join addresses on users.user_id=addresses.user_id").\ options(contains_eager(User.addresses, alias=eager_columns)) -The path given as the argument to :func:`~sqlalchemy.orm.contains_eager` needs +The path given as the argument to :func:`.contains_eager` needs to be a full path from the starting entity. For example if we were loading ``Users->orders->Order->items->Item``, the string version would look like:: @@ -438,22 +438,6 @@ query(User).options(contains_eager(User.orders, Order.items)) -A variant on :func:`~sqlalchemy.orm.contains_eager` is the -``contains_alias()`` option, which is used in the rare case that the parent -object is loaded from an alias within a user-defined SELECT statement:: - - # define an aliased UNION called 'ulist' - statement = users.select(users.c.user_id==7).union(users.select(users.c.user_id>7)).alias('ulist') - - # add on an eager load of "addresses" - statement = statement.outerjoin(addresses).select().apply_labels() - - # create query, indicating "ulist" is an alias for the main table, "addresses" property should - # be eager loaded - query = session.query(User).options(contains_alias('ulist'), contains_eager('addresses')) - - # results - r = query.from_statement(statement) Relation Loader API -------------------- @@ -466,6 +450,8 @@ .. autofunction:: eagerload_all +.. autofunction:: immediateload + .. autofunction:: joinedload .. autofunction:: joinedload_all diff -r 49167171134b -r 6308834a1f31 lib/sqlalchemy/orm/__init__.py --- a/lib/sqlalchemy/orm/__init__.py Tue Nov 22 19:01:21 2011 -0500 +++ b/lib/sqlalchemy/orm/__init__.py Thu Nov 24 10:47:10 2011 -0500 @@ -1182,7 +1182,7 @@ query.options(joinedload_all('orders.items.keywords'))... - will set all of 'orders', 'orders.items', and 'orders.items.keywords' to + will set all of ``orders``, ``orders.items``, and ``orders.items.keywords`` to load in one joined eager load. Individual descriptors are accepted as arguments as well:: @@ -1249,7 +1249,7 @@ query.options(subqueryload_all('orders.items.keywords'))... - will set all of 'orders', 'orders.items', and 'orders.items.keywords' to + will set all of ``orders``, ``orders.items``, and ``orders.items.keywords`` to load in one subquery eager load. Individual descriptors are accepted as arguments as well:: @@ -1300,6 +1300,17 @@ def immediateload(*keys): """Return a ``MapperOption`` that will convert the property of the given name or series of mapped attributes into an immediate load. + + The "immediate" load means the attribute will be fetched + with a separate SELECT statement per parent in the + same way as lazy loading - except the loader is guaranteed + to be called at load time before the parent object + is returned in the result. + + The normal behavior of lazy loading applies - if + the relationship is a simple many-to-one, and the child + object is already present in the :class:`.Session`, + no SELECT statement will be emitted. Used with :meth:`~sqlalchemy.orm.query.Query.options`. @@ -1311,11 +1322,35 @@ return strategies.EagerLazyOption(keys, lazy='immediate') def contains_alias(alias): - """Return a ``MapperOption`` that will indicate to the query that + """Return a :class:`.MapperOption` that will indicate to the query that the main table has been aliased. - `alias` is the string name or ``Alias`` object representing the - alias. + This is used in the very rare case that :func:`.contains_eager` + is being used in conjunction with a user-defined SELECT + statement that aliases the parent table. E.g.:: + + # define an aliased UNION called 'ulist' + statement = users.select(users.c.user_id==7).\\ + union(users.select(users.c.user_id>7)).\\ + alias('ulist') + + # add on an eager load of "addresses" + statement = statement.outerjoin(addresses).\\ + select().apply_labels() + + # create query, indicating "ulist" will be an + # alias for the main table, "addresses" + # property should be eager loaded + query = session.query(User).options( + contains_alias('ulist'), + contains_eager('addresses')) + + # then get results via the statement + results = query.from_statement(statement).all() + + :param alias: is the string name of an alias, or a + :class:`~.sql.expression.Alias` object representing + the alias. """ return AliasOption(alias) |