[Checkins] SVN: megrok.rdb/trunk/src/megrok/rdb/ Thanks to Laurence Rowe, introduce a flush to make sure that the

Martijn Faassen faassen at infrae.com
Fri Jul 11 08:50:41 EDT 2008


Log message for revision 88249:
  Thanks to Laurence Rowe, introduce a flush to make sure that the 
  primary key can be used as a container key (this is the default behavior).
  
  Also test the behavior of explicitly setting the key with rdb.key. 
  

Changed:
  U   megrok.rdb/trunk/src/megrok/rdb/README.txt
  U   megrok.rdb/trunk/src/megrok/rdb/components.py

-=-
Modified: megrok.rdb/trunk/src/megrok/rdb/README.txt
===================================================================
--- megrok.rdb/trunk/src/megrok/rdb/README.txt	2008-07-11 11:38:40 UTC (rev 88248)
+++ megrok.rdb/trunk/src/megrok/rdb/README.txt	2008-07-11 12:50:39 UTC (rev 88249)
@@ -41,14 +41,11 @@
 courses::
 
   >>> class Courses(rdb.Container):
-  ...    rdb.key('name')
+  ...    pass
 
-As you can see, we need to set up the attribute on which the key is
-based. We will use the ``name`` attribute, which we will define for
-the course later. Note that using the primary key attribute (such as
-``id`` in this example) is not a good idea if you expect the database
-to generate unique ids itself - the correct id will not be known yet
-before the object is commit to the database.
+That's all. If the ``rdb.key`` directive is not used the key in the
+container will be defined as the (possibly automatically assigned)
+primary key in the database.
 
 Now we can set up the ``Department`` class. This has the ``courses``
 relation that links to its courses::
@@ -196,7 +193,76 @@
 
   >>> for key, value in sorted(philosophy.courses.items()):
   ...     print key, value.name, value.department.name
-  Ethics Ethics Philosophy
-  Logic Logic Philosophy
-  Metaphysics Metaphysics Philosophy
+  1 Logic Philosophy
+  2 Ethics Philosophy
+  3 Metaphysics Philosophy
 
+As you can see, the automatically generated primary key is also used
+as the container key now.
+
+Custom key with ``rdb.key``
+---------------------------
+
+Let's now set up a different attribute to use as the container key.
+We will use the ``name`` attribute of the course.
+
+We'll set up the data model again, this time with a ``rdb.key`` on the
+``Courses`` class::
+
+  >>> metadata = rdb.MetaData()
+
+  >>> class Courses(rdb.Container):
+  ...    rdb.key('name')
+
+  >>> class Department(rdb.Model):
+  ...   rdb.metadata(metadata)
+  ...
+  ...   id = Column('id', Integer, primary_key=True)
+  ...   name = Column('name', String(50))
+  ... 
+  ...   courses = relation('Course', 
+  ...                       backref='department',
+  ...                       collection_class=Courses)
+
+  >>> class Course(rdb.Model):
+  ...   rdb.metadata(metadata)
+  ...
+  ...   id = Column('id', Integer, primary_key=True)
+  ...   department_id = Column('department_id', Integer, 
+  ...                           ForeignKey('department.id'))
+  ...   name = Column('name', String(50))
+
+We grok these new classes::
+
+  >>> grok_component('Courses', Courses)
+  True
+  >>> grok_component('Department', Department)
+  True
+  >>> grok_component('Course', Course)
+  True
+
+We don't need to change the engine, as the underlying relational
+database has remained the same. Let's set up another faculty with some
+departments::
+
+  >>> physics = Department(name="Physics")
+  >>> session.add(physics)
+  >>> quantum = Course(name="Quantum Mechanics")
+  >>> relativity = Course(name="Relativity")
+  >>> high_energy = Course(name="High Energy")
+  >>> session.add_all([quantum, relativity, high_energy])
+
+We'll now add these departments to the physics faculty::
+
+  >>> physics.courses.set(quantum)
+  >>> physics.courses.set(relativity)
+  >>> physics.courses.set(high_energy)
+
+We can now verify that the courses are there, with the names as the keys::
+
+  >>> for key, value in sorted(physics.courses.items()):
+  ...     print key, value.name, value.department.name
+  High Energy High Energy Physics
+  Quantum Mechanics Quantum Mechanics Physics
+  Relativity Relativity Physics
+

Modified: megrok.rdb/trunk/src/megrok/rdb/components.py
===================================================================
--- megrok.rdb/trunk/src/megrok/rdb/components.py	2008-07-11 11:38:40 UTC (rev 88248)
+++ megrok.rdb/trunk/src/megrok/rdb/components.py	2008-07-11 12:50:39 UTC (rev 88249)
@@ -1,4 +1,4 @@
-from sqlalchemy.orm.collections import MappedCollection
+from sqlalchemy.orm.collections import MappedCollection, collection
 
 from zope.interface import implements
 
@@ -37,3 +37,14 @@
         else:
             keyfunc = default_keyfunc
         MappedCollection.__init__(self, keyfunc=keyfunc)
+
+    @collection.internally_instrumented
+    @collection.appender
+    def set(self, value, _sa_initiator=None):
+        key = self.keyfunc(value)
+        if key is None:
+            session = Session()
+            session.flush()
+            key = self.keyfunc(value)
+        self.__setitem__(key, value, _sa_initiator)
+



More information about the Checkins mailing list