From: Mike Bayer Date: Thu, 24 Nov 2011 15:47:10 +0000 (-0500) Subject: - doc updates in loading X-Git-Tag: rel_0_7_4~51 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=74fe7b60b7adee1819c24c3532c278cfb0555516;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - 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 --- diff --git a/doc/build/orm/loading.rst b/doc/build/orm/loading.rst index 45b94191f7..16c17b4bdb 100644 --- a/doc/build/orm/loading.rst +++ b/doc/build/orm/loading.rst @@ -383,8 +383,8 @@ explicitly. Below it's used with a ``from_statement`` load:: # 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 @@ This is a string alias name or reference to an actual 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 @@ labels to the mapped :class:`~sqlalchemy.schema.Table`:: "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 @@ Or using the class-bound descriptor:: 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 @@ Relation Loader API .. autofunction:: eagerload_all +.. autofunction:: immediateload + .. autofunction:: joinedload .. autofunction:: joinedload_all diff --git a/lib/sqlalchemy/orm/__init__.py b/lib/sqlalchemy/orm/__init__.py index 8c44682f2d..4ea96c41ec 100644 --- a/lib/sqlalchemy/orm/__init__.py +++ b/lib/sqlalchemy/orm/__init__.py @@ -1182,7 +1182,7 @@ def joinedload_all(*keys, **kw): 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 @@ def subqueryload_all(*keys): 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 noload(*keys): 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 @@ def immediateload(*keys): 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)