From 7443d50d3102e345a367afea9019feb2d8c0c5a3 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Sun, 9 Dec 2012 14:12:22 -0500 Subject: [PATCH] - documentation and changelog for [ticket:2601] --- doc/build/changelog/changelog_08.rst | 8 ++++ doc/build/orm/query.rst | 3 ++ doc/build/orm/tutorial.rst | 3 +- lib/sqlalchemy/util/_collections.py | 66 ++++++++++++++++++++++++---- 4 files changed, 70 insertions(+), 10 deletions(-) diff --git a/doc/build/changelog/changelog_08.rst b/doc/build/changelog/changelog_08.rst index c472b444a7..0ed67b4893 100644 --- a/doc/build/changelog/changelog_08.rst +++ b/doc/build/changelog/changelog_08.rst @@ -6,6 +6,14 @@ .. changelog:: :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 dcd7ec40ea..e5358792ca 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 0e954946db..fadad8551b 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 244ed5c5ee..af82928067 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()) -- 2.47.2