diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2012-01-22 20:11:03 -0500 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2012-01-22 20:11:03 -0500 |
| commit | 82b90175f757ab287d882882355626a84dd8c185 (patch) | |
| tree | 210f7c5f9c340b33ca33c31d7420153c5cb49bcd /lib | |
| parent | ebaebfb2327a82240837778797bfffc60a7d6e7c (diff) | |
| download | sqlalchemy-82b90175f757ab287d882882355626a84dd8c185.tar.gz | |
- [feature] Added new capability to relationship
loader options to allow "default" loader strategies.
Pass '*' to any of joinedload(), lazyload(),
subqueryload(), or noload() and that becomes the
loader strategy used for all relationships,
except for those explicitly stated in the
Query. Thanks to up-and-coming contributor
Kent Bower for an exhaustive and well
written test suite ! [ticket:2351]
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/sqlalchemy/orm/__init__.py | 7 | ||||
| -rw-r--r-- | lib/sqlalchemy/orm/interfaces.py | 15 | ||||
| -rw-r--r-- | lib/sqlalchemy/orm/properties.py | 2 | ||||
| -rw-r--r-- | lib/sqlalchemy/orm/strategies.py | 7 |
4 files changed, 29 insertions, 2 deletions
diff --git a/lib/sqlalchemy/orm/__init__.py b/lib/sqlalchemy/orm/__init__.py index 58286e12b..9fd969e3b 100644 --- a/lib/sqlalchemy/orm/__init__.py +++ b/lib/sqlalchemy/orm/__init__.py @@ -1289,6 +1289,9 @@ def joinedload(*keys, **kw): # to joined-load across both, use joinedload_all() query(Order).options(joinedload_all(Order.items, Item.keywords)) + # set the default strategy to be 'joined' + query(Order).options(joinedload('*')) + :func:`joinedload` also accepts a keyword argument `innerjoin=True` which indicates using an inner join instead of an outer:: @@ -1360,6 +1363,7 @@ def joinedload_all(*keys, **kw): else: return strategies.EagerLazyOption(keys, lazy='joined', chained=True) + def eagerload(*args, **kwargs): """A synonym for :func:`joinedload()`.""" return joinedload(*args, **kwargs) @@ -1388,6 +1392,9 @@ def subqueryload(*keys): # to subquery-load across both, use subqueryload_all() query(Order).options(subqueryload_all(Order.items, Item.keywords)) + # set the default strategy to be 'subquery' + query(Order).options(subqueryload('*')) + See also: :func:`joinedload`, :func:`lazyload` """ diff --git a/lib/sqlalchemy/orm/interfaces.py b/lib/sqlalchemy/orm/interfaces.py index f570c10c2..7f2875e5a 100644 --- a/lib/sqlalchemy/orm/interfaces.py +++ b/lib/sqlalchemy/orm/interfaces.py @@ -306,16 +306,24 @@ class StrategizedProperty(MapperProperty): """ + strategy_wildcard_key = None + def _get_context_strategy(self, context, reduced_path): key = ('loaderstrategy', reduced_path) + cls = None if key in context.attributes: cls = context.attributes[key] + elif self.strategy_wildcard_key: + key = ('loaderstrategy', (self.strategy_wildcard_key,)) + if key in context.attributes: + cls = context.attributes[key] + + if cls: try: return self._strategies[cls] except KeyError: return self.__init_strategy(cls) - else: - return self.strategy + return self.strategy def _get_strategy(self, cls): try: @@ -494,6 +502,9 @@ class PropertyOption(MapperOption): while tokens: token = tokens.popleft() if isinstance(token, basestring): + # wildcard token + if token.endswith(':*'): + return [(token,)], [] sub_tokens = token.split(".", 1) token = sub_tokens[0] tokens.extendleft(sub_tokens[1:]) diff --git a/lib/sqlalchemy/orm/properties.py b/lib/sqlalchemy/orm/properties.py index cc06311f4..59c4cb3dc 100644 --- a/lib/sqlalchemy/orm/properties.py +++ b/lib/sqlalchemy/orm/properties.py @@ -185,6 +185,8 @@ class RelationshipProperty(StrategizedProperty): """ + strategy_wildcard_key = 'relationship:*' + def __init__(self, argument, secondary=None, primaryjoin=None, secondaryjoin=None, diff --git a/lib/sqlalchemy/orm/strategies.py b/lib/sqlalchemy/orm/strategies.py index 1bdd18cde..5f4b182d0 100644 --- a/lib/sqlalchemy/orm/strategies.py +++ b/lib/sqlalchemy/orm/strategies.py @@ -1319,6 +1319,13 @@ class EagerLazyOption(StrategizedOption): def __init__(self, key, lazy=True, chained=False, propagate_to_loaders=True ): + if isinstance(key[0], basestring) and key[0] == '*': + if len(key) != 1: + raise sa_exc.ArgumentError( + "Wildcard identifier '*' must " + "be specified alone.") + key = ("relationship:*",) + propagate_to_loaders = False super(EagerLazyOption, self).__init__(key) self.lazy = lazy self.chained = self.lazy in (False, 'joined', 'subquery') and chained |
