summaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2010-12-26 17:28:56 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2010-12-26 17:28:56 -0500
commit2e58059cbba6f612a86a9d03583e30717bcdd6c4 (patch)
tree10531fcd8c63da1426b19087775f89de023ef1c1 /examples
parent7dbb6bffc20bccb6e7087f9cfddb8463d9178204 (diff)
downloadsqlalchemy-2e58059cbba6f612a86a9d03583e30717bcdd6c4.tar.gz
- docs for mutable events example
Diffstat (limited to 'examples')
-rw-r--r--examples/mutable_events/__init__.py30
1 files changed, 28 insertions, 2 deletions
diff --git a/examples/mutable_events/__init__.py b/examples/mutable_events/__init__.py
index 813dc5abd..3b6363b96 100644
--- a/examples/mutable_events/__init__.py
+++ b/examples/mutable_events/__init__.py
@@ -1,14 +1,36 @@
"""
Illustrates how to build and use "mutable" types, such as dictionaries and
user-defined classes, as scalar attributes which detect in-place changes.
+These types don't make use of the "mutable=True" flag, which
+performs poorly within the ORM and is being phased out, instead allowing
+changes on data to associate change events with the parent object
+as they happen in the same way as any other mapped data member.
The example is based around the usage of the event model introduced in
-:ref:`event_toplevel`, along with the :func:`attributes.flag_modified` function
+:ref:`event_toplevel`, along with the :func:`~.attributes.flag_modified` function
which establishes the "dirty" flag on a particular mapped attribute. These
functions are encapsulated in a mixin called ``TrackMutationsMixin``.
-Subclassing ``dict`` to provide "mutation tracking" looks like::
+Subclassing ``dict`` to provide "mutation tracking", then
+applying it to a custom dictionary type, looks like::
+
+ class JSONEncodedDict(TypeDecorator):
+ "JSON dictionary type from the types documentation"
+
+ impl = VARCHAR
+
+ def process_bind_param(self, value, dialect):
+ if value is not None:
+ value = simplejson.dumps(value, use_decimal=True)
+ return value
+
+ def process_result_value(self, value, dialect):
+ if value is not None:
+ value = simplejson.loads(value, use_decimal=True)
+ return value
class MutationDict(TrackMutationsMixin, dict):
+ "Subclass dict to send mutation events to the owning object."
+
def __init__(self, other):
self.update(other)
@@ -20,17 +42,21 @@ Subclassing ``dict`` to provide "mutation tracking" looks like::
dict.__delitem__(self, key)
self.on_change()
+ # hypothetical mapping
Base = declarative_base()
class Foo(Base):
__tablename__ = 'foo'
id = Column(Integer, primary_key=True)
data = Column(JSONEncodedDict)
+ # add mutation tracking to `Foo.data` as a one off
MutationDict.associate_with_attribute(Foo.data)
The explicit step of associating ``MutationDict`` with ``Foo.data`` can be
automated across a class of columns using ``associate_with_type()``::
+ # add mutation tracking to all mapped attributes
+ # that use JSONEncodedDict
MutationDict.associate_with_type(JSONEncodedDict)
All subsequent mappings will have the ``MutationDict`` wrapper applied to