summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Kirtland <jek@discorporate.us>2007-07-31 23:50:50 +0000
committerJason Kirtland <jek@discorporate.us>2007-07-31 23:50:50 +0000
commitaac6598ecc400f9b3a8d69fae88e6882b9e7b597 (patch)
tree264621aff90a9b123de5e8a077057bb158109405
parent14f4c2e72d98554947a7cf884516d4d02ac8f56a (diff)
downloadsqlalchemy-aac6598ecc400f9b3a8d69fae88e6882b9e7b597.tar.gz
Changed __colset__ to __composite_values__ [ticket:692] (sort of)
-rw-r--r--lib/sqlalchemy/orm/__init__.py64
-rw-r--r--lib/sqlalchemy/orm/properties.py12
-rw-r--r--lib/sqlalchemy/orm/query.py4
-rw-r--r--lib/sqlalchemy/orm/strategies.py7
-rw-r--r--test/orm/mapper.py7
5 files changed, 58 insertions, 36 deletions
diff --git a/lib/sqlalchemy/orm/__init__.py b/lib/sqlalchemy/orm/__init__.py
index 42964545d..3d8461dfd 100644
--- a/lib/sqlalchemy/orm/__init__.py
+++ b/lib/sqlalchemy/orm/__init__.py
@@ -253,30 +253,46 @@ def composite(class_, *cols, **kwargs):
"""Return a composite column-based property for use with a Mapper.
This is very much like a column-based property except the given class
- is used to construct values composed of one or more columns. The class must
- implement a constructor with positional arguments matching the order of
- columns given, as well as a __colset__() method which returns its attributes
- in column order.
+ is used to represent "composite" values composed of one or more columns.
+
+ The class must implement a constructor with positional arguments matching
+ the order of columns supplied here, as well as a __composite_values__()
+ method which returns values in the same order.
+
+ A simple example is representing separate two columns in a table as a
+ single, first-class "Point" object::
+
+ class Point(object):
+ def __init__(self, x, y):
+ self.x = x
+ self.y = y
+ def __composite_values__(self):
+ return (self.x, self.y)
+
+ # and then in the mapping:
+ ... composite(Point, mytable.c.x, mytable.c.y) ...
+
+ Arguments are:
- class\_
- the "composite type" class.
+ class\_
+ The "composite type" class.
- \*cols
- list of Column objects to be mapped.
+ \*cols
+ List of Column objects to be mapped.
- group
- a group name for this property when marked as deferred.
+ group
+ A group name for this property when marked as deferred.
- deferred
- when True, the column property is "deferred", meaning that
- it does not load immediately, and is instead loaded when the
- attribute is first accessed on an instance. See also
- [sqlalchemy.orm#deferred()].
+ deferred
+ When True, the column property is "deferred", meaning that
+ it does not load immediately, and is instead loaded when the
+ attribute is first accessed on an instance. See also
+ [sqlalchemy.orm#deferred()].
- comparator
- an optional instance of [sqlalchemy.orm#PropComparator] which
- provides SQL expression generation functions for this composite
- type.
+ comparator
+ An optional instance of [sqlalchemy.orm#PropComparator] which
+ provides SQL expression generation functions for this composite
+ type.
"""
return CompositeProperty(class_, *cols, **kwargs)
@@ -483,8 +499,7 @@ def extension(ext):
return ExtensionOption(ext)
def eagerload(name):
- """Return a ``MapperOption`` that will convert the property of the
- given name into an eager load.
+ """Return a ``MapperOption`` that will convert the property of the given name into an eager load.
Used with ``query.options()``.
"""
@@ -492,11 +507,10 @@ def eagerload(name):
return strategies.EagerLazyOption(name, lazy=False)
def eagerload_all(name):
- """Return a ``MapperOption`` that will convert all
- properties along the given dot-separated path into an
- eager load.
+ """Return a ``MapperOption`` that will convert all properties along the given dot-separated path into an eager load.
- e.g::
+ For example, this::
+
query.options(eagerload_all('orders.items.keywords'))...
will set all of 'orders', 'orders.items', and 'orders.items.keywords'
diff --git a/lib/sqlalchemy/orm/properties.py b/lib/sqlalchemy/orm/properties.py
index 600dab41f..c7bdc4274 100644
--- a/lib/sqlalchemy/orm/properties.py
+++ b/lib/sqlalchemy/orm/properties.py
@@ -100,12 +100,12 @@ class CompositeProperty(ColumnProperty):
obj = getattr(object, self.key, None)
if obj is None:
obj = self.composite_class(*[None for c in self.columns])
- for a, b in zip(self.columns, value.__colset__()):
+ for a, b in zip(self.columns, value.__composite_values__()):
if a is column:
setattr(obj, b, value)
def get_col_value(self, column, value):
- for a, b in zip(self.columns, value.__colset__()):
+ for a, b in zip(self.columns, value.__composite_values__()):
if a is column:
return b
@@ -114,10 +114,14 @@ class CompositeProperty(ColumnProperty):
if other is None:
return sql.and_(*[a==None for a in self.prop.columns])
else:
- return sql.and_(*[a==b for a, b in zip(self.prop.columns, other.__colset__())])
+ return sql.and_(*[a==b for a, b in
+ zip(self.prop.columns,
+ other.__composite_values__())])
def __ne__(self, other):
- return sql.or_(*[a!=b for a, b in zip(self.prop.columns, other.__colset__())])
+ return sql.or_(*[a!=b for a, b in
+ zip(self.prop.columns,
+ other.__composite_values__())])
class PropertyLoader(StrategizedProperty):
"""Describes an object property that holds a single item or list
diff --git a/lib/sqlalchemy/orm/query.py b/lib/sqlalchemy/orm/query.py
index 37d5b10a3..1b5871858 100644
--- a/lib/sqlalchemy/orm/query.py
+++ b/lib/sqlalchemy/orm/query.py
@@ -76,8 +76,8 @@ class Query(object):
# convert composite types to individual args
# TODO: account for the order of columns in the
# ColumnProperty it corresponds to
- if hasattr(ident, '__colset__'):
- ident = ident.__colset__()
+ if hasattr(ident, '__composite_values__'):
+ ident = ident.__composite_values__()
key = self.mapper.identity_key_from_primary_key(ident)
return self._get(key, ident, **kwargs)
diff --git a/lib/sqlalchemy/orm/strategies.py b/lib/sqlalchemy/orm/strategies.py
index 8a0cc6035..6e2860f3a 100644
--- a/lib/sqlalchemy/orm/strategies.py
+++ b/lib/sqlalchemy/orm/strategies.py
@@ -37,9 +37,12 @@ class ColumnLoader(LoaderStrategy):
def _init_composite_attribute(self):
self.logger.info("register managed composite attribute %s on class %s" % (self.key, self.parent.class_.__name__))
def copy(obj):
- return self.parent_property.composite_class(*obj.__colset__())
+ return self.parent_property.composite_class(
+ *obj.__composite_values__())
def compare(a, b):
- for col, aprop, bprop in zip(self.columns, a.__colset__(), b.__colset__()):
+ for col, aprop, bprop in zip(self.columns,
+ a.__composite_values__(),
+ b.__composite_values__()):
if not col.type.compare_values(aprop, bprop):
return False
else:
diff --git a/test/orm/mapper.py b/test/orm/mapper.py
index 12670c654..414a1936f 100644
--- a/test/orm/mapper.py
+++ b/test/orm/mapper.py
@@ -818,7 +818,7 @@ class CompositeTypesTest(ORMTest):
def __init__(self, x, y):
self.x = x
self.y = y
- def __colset__(self):
+ def __composite_values__(self):
return [self.x, self.y]
def __eq__(self, other):
return other.x == self.x and other.y == self.y
@@ -893,8 +893,9 @@ class CompositeTypesTest(ORMTest):
def __init__(self, id, version):
self.id = id
self.version = version
- def __colset__(self):
- return [self.id, self.version]
+ def __composite_values__(self):
+ # a tuple this time
+ return (self.id, self.version)
def __eq__(self, other):
return other.id == self.id and other.version == self.version
def __ne__(self, other):