summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/orm/__init__.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sqlalchemy/orm/__init__.py')
-rw-r--r--lib/sqlalchemy/orm/__init__.py204
1 files changed, 120 insertions, 84 deletions
diff --git a/lib/sqlalchemy/orm/__init__.py b/lib/sqlalchemy/orm/__init__.py
index 2466a2763..9c23fd409 100644
--- a/lib/sqlalchemy/orm/__init__.py
+++ b/lib/sqlalchemy/orm/__init__.py
@@ -9,63 +9,98 @@ Functional constructs for ORM configuration.
See the SQLAlchemy object relational tutorial and mapper configuration
documentation for an overview of how this module is used.
+
"""
-from sqlalchemy.orm.mapper import Mapper, object_mapper, class_mapper, _mapper_registry
-from sqlalchemy.orm.interfaces import MapperExtension, EXT_CONTINUE, EXT_STOP, EXT_PASS, ExtensionOption, PropComparator
-from sqlalchemy.orm.properties import SynonymProperty, ComparableProperty, PropertyLoader, ColumnProperty, CompositeProperty, BackRef
+from sqlalchemy.orm import exc
+from sqlalchemy.orm.mapper import \
+ Mapper, _mapper_registry, class_mapper, object_mapper
+from sqlalchemy.orm.interfaces import \
+ EXT_CONTINUE, EXT_STOP, ExtensionOption, InstrumentationManager, \
+ MapperExtension, PropComparator, SessionExtension
+from sqlalchemy.orm.properties import \
+ BackRef, ColumnProperty, ComparableProperty, CompositeProperty, \
+ PropertyLoader, SynonymProperty
from sqlalchemy.orm import mapper as mapperlib
from sqlalchemy.orm import strategies
-from sqlalchemy.orm.query import Query, aliased
-from sqlalchemy.orm.util import polymorphic_union, create_row_adapter
+from sqlalchemy.orm.query import AliasOption, Query
+from sqlalchemy.orm.util import \
+ AliasedClass as aliased, join, outerjoin, polymorphic_union, with_parent
+from sqlalchemy.sql import util as sql_util
from sqlalchemy.orm.session import Session as _Session
from sqlalchemy.orm.session import object_session, sessionmaker
from sqlalchemy.orm.scoping import ScopedSession
-
-
-__all__ = [ 'relation', 'column_property', 'composite', 'backref', 'eagerload',
- 'eagerload_all', 'lazyload', 'noload', 'deferred', 'defer',
- 'undefer', 'undefer_group', 'extension', 'mapper', 'clear_mappers',
- 'compile_mappers', 'class_mapper', 'object_mapper', 'sessionmaker',
- 'scoped_session', 'dynamic_loader', 'MapperExtension',
- 'polymorphic_union', 'comparable_property',
- 'create_session', 'synonym', 'contains_alias', 'Query', 'aliased',
- 'contains_eager', 'EXT_CONTINUE', 'EXT_STOP', 'EXT_PASS',
- 'object_session', 'PropComparator' ]
+from sqlalchemy import util as sa_util
+
+__all__ = (
+ 'EXT_CONTINUE',
+ 'EXT_STOP',
+ 'InstrumentationManager',
+ 'MapperExtension',
+ 'PropComparator',
+ 'Query',
+ 'aliased',
+ 'backref',
+ 'class_mapper',
+ 'clear_mappers',
+ 'column_property',
+ 'comparable_property',
+ 'compile_mappers',
+ 'composite',
+ 'contains_alias',
+ 'contains_eager',
+ 'create_session',
+ 'defer',
+ 'deferred',
+ 'dynamic_loader',
+ 'eagerload',
+ 'eagerload_all',
+ 'extension',
+ 'lazyload',
+ 'mapper',
+ 'noload',
+ 'object_mapper',
+ 'object_session',
+ 'polymorphic_union',
+ 'relation',
+ 'scoped_session',
+ 'sessionmaker',
+ 'synonym',
+ 'undefer',
+ 'undefer_group',
+ )
def scoped_session(session_factory, scopefunc=None):
- """Provides thread-local management of Sessions.
-
- This is a front-end function to the [sqlalchemy.orm.scoping#ScopedSession]
- class.
+ """Provides thread-local management of Sessions.
- Usage::
+ This is a front-end function to the [sqlalchemy.orm.scoping#ScopedSession]
+ class.
- Session = scoped_session(sessionmaker(autoflush=True))
+ Usage::
- To instantiate a Session object which is part of the scoped
- context, instantiate normally::
+ Session = scoped_session(sessionmaker(autoflush=True))
- session = Session()
+ To instantiate a Session object which is part of the scoped context,
+ instantiate normally::
- Most session methods are available as classmethods from
- the scoped session::
+ session = Session()
- Session.commit()
- Session.close()
+ Most session methods are available as classmethods from the scoped
+ session::
- To map classes so that new instances are saved in the current
- Session automatically, as well as to provide session-aware
- class attributes such as "query", use the `mapper` classmethod
- from the scoped session::
+ Session.commit()
+ Session.close()
- mapper = Session.mapper
- mapper(Class, table, ...)
+ To map classes so that new instances are saved in the current Session
+ automatically, as well as to provide session-aware class attributes such
+ as "query", use the `mapper` classmethod from the scoped session::
- """
+ mapper = Session.mapper
+ mapper(Class, table, ...)
- return ScopedSession(session_factory, scopefunc=scopefunc)
+ """
+ return ScopedSession(session_factory, scopefunc=scopefunc)
def create_session(bind=None, **kwargs):
"""create a new [sqlalchemy.orm.session#Session].
@@ -76,26 +111,36 @@ def create_session(bind=None, **kwargs):
It is recommended to use the [sqlalchemy.orm#sessionmaker()] function
instead of create_session().
"""
+
+ if 'transactional' in kwargs:
+ sa_util.warn_deprecated(
+ "The 'transactional' argument to sessionmaker() is deprecated; "
+ "use autocommit=True|False instead.")
+ if 'autocommit' in kwargs:
+ raise TypeError('Specify autocommit *or* transactional, not both.')
+ kwargs['autocommit'] = not kwargs.pop('transactional')
+
kwargs.setdefault('autoflush', False)
- kwargs.setdefault('transactional', False)
+ kwargs.setdefault('autocommit', True)
+ kwargs.setdefault('autoexpire', False)
return _Session(bind=bind, **kwargs)
def relation(argument, secondary=None, **kwargs):
"""Provide a relationship of a primary Mapper to a secondary Mapper.
- This corresponds to a parent-child or associative table relationship.
- The constructed class is an instance of [sqlalchemy.orm.properties#PropertyLoader].
+ This corresponds to a parent-child or associative table relationship. The
+ constructed class is an instance of
+ [sqlalchemy.orm.properties#PropertyLoader].
argument
a class or Mapper instance, representing the target of the relation.
secondary
for a many-to-many relationship, specifies the intermediary table. The
- ``secondary`` keyword argument should generally only be used for a table
- that is not otherwise expressed in any class mapping. In particular,
- using the Association Object Pattern is
- generally mutually exclusive against using the ``secondary`` keyword
- argument.
+ ``secondary`` keyword argument should generally only be used for a
+ table that is not otherwise expressed in any class mapping. In
+ particular, using the Association Object Pattern is generally mutually
+ exclusive against using the ``secondary`` keyword argument.
\**kwargs follow:
@@ -482,8 +527,8 @@ def mapper(class_, local_table=None, *args, **params):
which will identify the class/mapper combination to be used
with a particular row. Requires the ``polymorphic_identity``
value to be set for all mappers in the inheritance
- hierarchy. The column specified by ``polymorphic_on`` is
- usually a column that resides directly within the base
+ hierarchy. The column specified by ``polymorphic_on`` is
+ usually a column that resides directly within the base
mapper's mapped table; alternatively, it may be a column
that is only present within the <selectable> portion
of the ``with_polymorphic`` argument.
@@ -532,7 +577,7 @@ def mapper(class_, local_table=None, *args, **params):
to be used against this mapper's selectable unit. This is
normally simply the primary key of the `local_table`, but
can be overridden here.
-
+
with_polymorphic
A tuple in the form ``(<classes>, <selectable>)`` indicating the
default style of "polymorphic" loading, that is, which tables
@@ -549,9 +594,9 @@ def mapper(class_, local_table=None, *args, **params):
which load from a "concrete" inheriting table, the <selectable>
argument is required, since it usually requires more complex
UNION queries.
-
+
select_table
- Deprecated. Synonymous with
+ Deprecated. Synonymous with
``with_polymorphic=('*', <selectable>)``.
version_id_col
@@ -677,15 +722,16 @@ def extension(ext):
return ExtensionOption(ext)
-def eagerload(name, mapper=None):
+def eagerload(*keys):
"""Return a ``MapperOption`` that will convert the property of the given name into an eager load.
Used with ``query.options()``.
"""
- return strategies.EagerLazyOption(name, lazy=False, mapper=mapper)
+ return strategies.EagerLazyOption(keys, lazy=False)
+eagerload = sa_util.array_as_starargs_fn_decorator(eagerload)
-def eagerload_all(name, mapper=None):
+def eagerload_all(*keys):
"""Return a ``MapperOption`` that will convert all properties along the given dot-separated path into an eager load.
For example, this::
@@ -698,25 +744,27 @@ def eagerload_all(name, mapper=None):
Used with ``query.options()``.
"""
- return strategies.EagerLazyOption(name, lazy=False, chained=True, mapper=mapper)
+ return strategies.EagerLazyOption(keys, lazy=False, chained=True)
+eagerload_all = sa_util.array_as_starargs_fn_decorator(eagerload_all)
-def lazyload(name, mapper=None):
+def lazyload(*keys):
"""Return a ``MapperOption`` that will convert the property of the
given name into a lazy load.
Used with ``query.options()``.
"""
- return strategies.EagerLazyOption(name, lazy=True, mapper=mapper)
+ return strategies.EagerLazyOption(keys, lazy=True)
+lazyload = sa_util.array_as_starargs_fn_decorator(lazyload)
-def noload(name):
+def noload(*keys):
"""Return a ``MapperOption`` that will convert the property of the
given name into a non-load.
Used with ``query.options()``.
"""
- return strategies.EagerLazyOption(name, lazy=None)
+ return strategies.EagerLazyOption(keys, lazy=None)
def contains_alias(alias):
"""Return a ``MapperOption`` that will indicate to the query that
@@ -726,22 +774,9 @@ def contains_alias(alias):
alias.
"""
- class AliasedRow(MapperExtension):
- def __init__(self, alias):
- self.alias = alias
- if isinstance(self.alias, basestring):
- self.translator = None
- else:
- self.translator = create_row_adapter(alias)
-
- def translate_row(self, mapper, context, row):
- if not self.translator:
- self.translator = create_row_adapter(mapper.mapped_table.alias(self.alias))
- return self.translator(row)
-
- return ExtensionOption(AliasedRow(alias))
+ return AliasOption(alias)
-def contains_eager(key, alias=None, decorator=None):
+def contains_eager(*keys, **kwargs):
"""Return a ``MapperOption`` that will indicate to the query that
the given attribute will be eagerly loaded.
@@ -752,30 +787,31 @@ def contains_eager(key, alias=None, decorator=None):
`alias` is the string name of an alias, **or** an ``sql.Alias``
object, which represents the aliased columns in the query. This
argument is optional.
-
- `decorator` is mutually exclusive of `alias` and is a
- row-processing function which will be applied to the incoming row
- before sending to the eager load handler. use this for more
- sophisticated row adjustments beyond a straight alias.
"""
+ alias = kwargs.pop('alias', None)
+ if kwargs:
+ raise exceptions.ArgumentError("Invalid kwargs for contains_eager: %r" % kwargs.keys())
+
+ return (strategies.EagerLazyOption(keys, lazy=False), strategies.LoadEagerFromAliasOption(keys, alias=alias))
+contains_eager = sa_util.array_as_starargs_fn_decorator(contains_eager)
- return (strategies.EagerLazyOption(key, lazy=False), strategies.RowDecorateOption(key, alias=alias, decorator=decorator))
-
-def defer(name):
+def defer(*keys):
"""Return a ``MapperOption`` that will convert the column property
of the given name into a deferred load.
Used with ``query.options()``"""
- return strategies.DeferredOption(name, defer=True)
+ return strategies.DeferredOption(keys, defer=True)
+defer = sa_util.array_as_starargs_fn_decorator(defer)
-def undefer(name):
+def undefer(*keys):
"""Return a ``MapperOption`` that will convert the column property
of the given name into a non-deferred (regular column) load.
Used with ``query.options()``.
"""
- return strategies.DeferredOption(name, defer=False)
+ return strategies.DeferredOption(keys, defer=False)
+undefer = sa_util.array_as_starargs_fn_decorator(undefer)
def undefer_group(name):
"""Return a ``MapperOption`` that will convert the given