summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2012-01-22 20:11:03 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2012-01-22 20:11:03 -0500
commit82b90175f757ab287d882882355626a84dd8c185 (patch)
tree210f7c5f9c340b33ca33c31d7420153c5cb49bcd /lib
parentebaebfb2327a82240837778797bfffc60a7d6e7c (diff)
downloadsqlalchemy-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__.py7
-rw-r--r--lib/sqlalchemy/orm/interfaces.py15
-rw-r--r--lib/sqlalchemy/orm/properties.py2
-rw-r--r--lib/sqlalchemy/orm/strategies.py7
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