summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2012-12-09 14:12:22 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2012-12-09 14:12:22 -0500
commit7443d50d3102e345a367afea9019feb2d8c0c5a3 (patch)
tree23543849dfd8a49cb09c97ba50c18056dc03cd86
parentfef25bdcf9cf9f7936a569acd3b9eb850f1c3fd9 (diff)
downloadsqlalchemy-7443d50d3102e345a367afea9019feb2d8c0c5a3.tar.gz
- documentation and changelog for [ticket:2601]
-rw-r--r--doc/build/changelog/changelog_08.rst8
-rw-r--r--doc/build/orm/query.rst3
-rw-r--r--doc/build/orm/tutorial.rst3
-rw-r--r--lib/sqlalchemy/util/_collections.py66
4 files changed, 70 insertions, 10 deletions
diff --git a/doc/build/changelog/changelog_08.rst b/doc/build/changelog/changelog_08.rst
index c472b444a..0ed67b489 100644
--- a/doc/build/changelog/changelog_08.rst
+++ b/doc/build/changelog/changelog_08.rst
@@ -7,6 +7,14 @@
:version: 0.8.0b2
.. change::
+ :tags: orm, feature
+ :tickets: 2601
+
+ Added :meth:`.KeyedTuple._asdict` and :attr:`.KeyedTuple._fields`
+ to the :class:`.KeyedTuple` class to provide some degree of compatibility
+ with the Python standard library ``collections.namedtuple()``.
+
+ .. change::
:tags: sql, bug
:tickets: 2631
diff --git a/doc/build/orm/query.rst b/doc/build/orm/query.rst
index dcd7ec40e..e5358792c 100644
--- a/doc/build/orm/query.rst
+++ b/doc/build/orm/query.rst
@@ -32,6 +32,9 @@ ORM-Specific Query Constructs
.. autoclass:: sqlalchemy.orm.util.AliasedInsp
+.. autoclass:: sqlalchemy.util.KeyedTuple
+ :members: keys, _fields, _asdict
+
.. autofunction:: join
.. autofunction:: outerjoin
diff --git a/doc/build/orm/tutorial.rst b/doc/build/orm/tutorial.rst
index 0e954946d..fadad8551 100644
--- a/doc/build/orm/tutorial.rst
+++ b/doc/build/orm/tutorial.rst
@@ -623,7 +623,8 @@ is expressed as tuples:
fred Fred Flinstone
The tuples returned by :class:`~sqlalchemy.orm.query.Query` are *named*
-tuples, and can be treated much like an ordinary Python object. The names are
+tuples, supplied by the :class:`.KeyedTuple` class, and can be treated much like an
+ordinary Python object. The names are
the same as the attribute's name for an attribute, and the class name for a
class:
diff --git a/lib/sqlalchemy/util/_collections.py b/lib/sqlalchemy/util/_collections.py
index 244ed5c5e..af8292806 100644
--- a/lib/sqlalchemy/util/_collections.py
+++ b/lib/sqlalchemy/util/_collections.py
@@ -16,18 +16,39 @@ EMPTY_SET = frozenset()
class KeyedTuple(tuple):
- """tuple() subclass that adds labeled names.
+ """``tuple`` subclass that adds labeled names.
- Unlike collections.namedtuple, this is
- an ad-hoc data structure, not a factory
- for new types.
+ E.g.::
- It's pickleable in-place without the need for stack
- frame manipulation, new KeyedTuple types can be created
- very quickly and simply (look at the source
- to collections.namedtuple for contrast).
+ >>> k = KeyedTuple([1, 2, 3], labels=["one", "two", "three"])
+ >>> k.one
+ 1
+ >>> k.two
+ 2
- Is used by :class:`.Query` to return result rows.
+ Result rows returned by :class:`.Query` that contain multiple
+ ORM entities and/or column expressions make use of this
+ class to return rows.
+
+ The :class:`.KeyedTuple` exhibits similar behavior to the
+ ``collections.namedtuple()`` construct provided in the Python
+ standard library, however is architected very differently.
+ Unlike ``collections.namedtuple()``, :class:`.KeyedTuple` is
+ does not rely on creation of custom subtypes in order to represent
+ a new series of keys, instead each :class:`.KeyedTuple` instance
+ receives its list of keys in place. The subtype approach
+ of ``collections.namedtuple()`` introduces significant complexity
+ and performance overhead, which is not necessary for the
+ :class:`.Query` object's use case.
+
+ .. versionchanged:: 0.8
+ Compatibility methods with ``collections.namedtuple()`` have been
+ added including :attr:`.KeyedTuple._fields` and
+ :meth:`.KeyedTuple._asdict`.
+
+ .. seealso::
+
+ :ref:`ormtutorial_querying`
"""
@@ -40,13 +61,40 @@ class KeyedTuple(tuple):
return t
def keys(self):
+ """Return a list of string key names for this :class:`.KeyedTuple`.
+
+ .. seealso::
+
+ :attr:`.KeyedTuple._fields`
+
+ """
+
return [l for l in self._labels if l is not None]
@property
def _fields(self):
+ """Return a tuple of string key names for this :class:`.KeyedTuple`.
+
+ This method provides compatibility with ``collections.namedtuple()``.
+
+ .. versionadded:: 0.8
+
+ .. seealso::
+
+ :meth:`.KeyedTuple.keys`
+
+ """
return tuple(self.keys())
def _asdict(self):
+ """Return the contents of this :class:`.KeyedTuple` as a dictionary.
+
+ This method provides compatibility with ``collections.namedtuple()``,
+ with the exception that the dictionary returned is **not** ordered.
+
+ .. versionadded:: 0.8
+
+ """
return dict((key, self.__dict__[key]) for key in self.keys())