]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- modernizing examples
authorMike Bayer <mike_mp@zzzcomputing.com>
Mon, 9 Aug 2010 00:58:05 +0000 (20:58 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Mon, 9 Aug 2010 00:58:05 +0000 (20:58 -0400)
examples/derived_attributes/attributes.py
examples/inheritance/concrete.py
examples/inheritance/polymorph.py
examples/inheritance/single.py
examples/poly_assoc/poly_assoc.py
examples/poly_assoc/poly_assoc_fk.py
examples/poly_assoc/poly_assoc_generic.py
examples/versioning/__init__.py
examples/versioning/history_meta.py

index 15af7b2adb65645e9fe72e02f6e191f6b49ce82c..ade2a4ed31106cd3393bb25ad56695ae979b7ad7 100644 (file)
@@ -1,7 +1,7 @@
 
 import new
 
-class MethodDescriptor(object):
+class hybrid(object):
     def __init__(self, func):
         self.func = func
     def __get__(self, instance, owner):
@@ -10,8 +10,8 @@ class MethodDescriptor(object):
         else:
             return new.instancemethod(self.func, instance, owner)
 
-class PropertyDescriptor(object):
-    def __init__(self, fget, fset, fdel):
+class hybrid_property(object):
+    def __init__(self, fget, fset=None, fdel=None):
         self.fget = fget
         self.fset = fset
         self.fdel = fdel
@@ -24,17 +24,15 @@ class PropertyDescriptor(object):
         self.fset(instance, value)
     def __delete__(self, instance):
         self.fdel(instance)
-        
-def hybrid(func):
-    return MethodDescriptor(func)
-
-def hybrid_property(fget, fset=None, fdel=None):
-    return PropertyDescriptor(fget, fset, fdel)
+    
+    def setter(self, fset):
+        self.fset = fset
+        return self
 
 ### Example code
 
 from sqlalchemy import MetaData, Table, Column, Integer
-from sqlalchemy.orm import mapper, create_session
+from sqlalchemy.orm import mapper, sessionmaker
 
 metadata = MetaData('sqlite://')
 metadata.bind.echo = True
@@ -91,7 +89,7 @@ mapper(Interval2, interval_table2)
 
 print "Create the data"
 
-session = create_session()
+session = sessionmaker()()
 
 intervals = [Interval1(1,4), Interval1(3,15), Interval1(11,16)]
 
@@ -99,18 +97,16 @@ for interval in intervals:
     session.add(interval)
     session.add(Interval2(interval.start, interval.length))
 
-session.flush()
-
-print "Clear the cache and do some queries"
+session.commit()
 
-session.expunge_all()
 
 for Interval in (Interval1, Interval2):
     print "Querying using interval class %s" % Interval.__name__
     
     print
     print '-- length less than 10'
-    print [(i, i.length) for i in session.query(Interval).filter(Interval.length < 10).all()]
+    print [(i, i.length) for i in 
+                session.query(Interval).filter(Interval.length < 10).all()]
     
     print
     print '-- contains 12'
@@ -119,6 +115,8 @@ for Interval in (Interval1, Interval2):
     print
     print '-- intersects 2..10'
     other = Interval1(2,10)
-    result = session.query(Interval).filter(Interval.intersects(other)).order_by(Interval.length).all()
+    result = session.query(Interval).\
+                    filter(Interval.intersects(other)).\
+                    order_by(Interval.length).all()
     print [(interval, interval.intersects(other)) for interval in result]
 
index c50513b55559ad14d7e600d352a65c7576dfd3f9..eb832a55d9fe2b4467897c17d41051d96f533714 100644 (file)
@@ -1,5 +1,6 @@
-from sqlalchemy import create_engine, MetaData, Table, Column, Integer, String
-from sqlalchemy.orm import mapper, create_session, polymorphic_union
+from sqlalchemy import create_engine, MetaData, Table, Column, Integer, \
+    String
+from sqlalchemy.orm import mapper, sessionmaker, polymorphic_union
 
 metadata = MetaData()
 
@@ -30,14 +31,16 @@ class Manager(Employee):
         self.name = name
         self.manager_data = manager_data
     def __repr__(self):
-        return self.__class__.__name__ + " " + self.name + " " +  self.manager_data
+        return self.__class__.__name__ + " " + \
+                    self.name + " " +  self.manager_data
     
 class Engineer(Employee):
     def __init__(self, name, engineer_info):
         self.name = name
         self.engineer_info = engineer_info
     def __repr__(self):
-        return self.__class__.__name__ + " " + self.name + " " +  self.engineer_info
+        return self.__class__.__name__ + " " + \
+                    self.name + " " +  self.engineer_info
 
 
 pjoin = polymorphic_union({
@@ -46,11 +49,15 @@ pjoin = polymorphic_union({
 }, 'type', 'pjoin')
 
 employee_mapper = mapper(Employee, pjoin, polymorphic_on=pjoin.c.type)
-manager_mapper = mapper(Manager, managers_table, inherits=employee_mapper, concrete=True, polymorphic_identity='manager')
-engineer_mapper = mapper(Engineer, engineers_table, inherits=employee_mapper, concrete=True, polymorphic_identity='engineer')
+manager_mapper = mapper(Manager, managers_table,
+                        inherits=employee_mapper, concrete=True,
+                        polymorphic_identity='manager')
+engineer_mapper = mapper(Engineer, engineers_table,
+                         inherits=employee_mapper, concrete=True,
+                         polymorphic_identity='engineer')
 
 
-session = create_session(bind=engine)
+session = sessionmaker(engine)()
 
 m1 = Manager("pointy haired boss", "manager1")
 e1 = Engineer("wally", "engineer1")
@@ -59,8 +66,7 @@ e2 = Engineer("dilbert", "engineer2")
 session.add(m1)
 session.add(e1)
 session.add(e2)
-session.flush()
+session.commit()
 
-employees = session.query(Employee)
-print [e for e in employees]
+print session.query(Employee).all()
 
index 7ca207f9fd779014d3a8eb0235282becfb4195cb..8723180604891e61c5987de45befef411085eff0 100644 (file)
@@ -1,19 +1,20 @@
-from sqlalchemy import MetaData, Table, Column, Integer, String, ForeignKey
-from sqlalchemy.orm import mapper, relationship, create_session
-import sets
+from sqlalchemy import MetaData, Table, Column, Integer, String, \
+    ForeignKey, create_engine
+from sqlalchemy.orm import mapper, relationship, sessionmaker
+
 
 # this example illustrates a polymorphic load of two classes
 
-metadata = MetaData('sqlite://')
-metadata.bind.echo = True
+metadata = MetaData()
 
 # a table to store companies
 companies = Table('companies', metadata, 
    Column('company_id', Integer, primary_key=True),
    Column('name', String(50)))
 
-# we will define an inheritance relationship between the table "people" and "engineers",
-# and a second inheritance relationship between the table "people" and "managers"
+# we will define an inheritance relationship between the table "people" and
+# "engineers", and a second inheritance relationship between the table
+# "people" and "managers"
 people = Table('people', metadata, 
    Column('person_id', Integer, primary_key=True),
    Column('company_id', Integer, ForeignKey('companies.company_id')),
@@ -21,20 +22,20 @@ people = Table('people', metadata,
    Column('type', String(30)))
    
 engineers = Table('engineers', metadata, 
-   Column('person_id', Integer, ForeignKey('people.person_id'), primary_key=True),
+   Column('person_id', Integer, ForeignKey('people.person_id'), 
+                                    primary_key=True),
    Column('status', String(30)),
    Column('engineer_name', String(50)),
    Column('primary_language', String(50)),
   )
    
 managers = Table('managers', metadata, 
-   Column('person_id', Integer, ForeignKey('people.person_id'), primary_key=True),
+   Column('person_id', Integer, ForeignKey('people.person_id'), 
+                                    primary_key=True),
    Column('status', String(30)),
    Column('manager_name', String(50))
    )
    
-metadata.create_all()
-
 # create our classes.  The Engineer and Manager classes extend from Person.
 class Person(object):
     def __init__(self, **kwargs):
@@ -44,10 +45,14 @@ class Person(object):
         return "Ordinary person %s" % self.name
 class Engineer(Person):
     def __repr__(self):
-        return "Engineer %s, status %s, engineer_name %s, primary_language %s" % (self.name, self.status, self.engineer_name, self.primary_language)
+        return "Engineer %s, status %s, engineer_name %s, "\
+                "primary_language %s" % \
+                    (self.name, self.status, 
+                        self.engineer_name, self.primary_language)
 class Manager(Person):
     def __repr__(self):
-        return "Manager %s, status %s, manager_name %s" % (self.name, self.status, self.manager_name)
+        return "Manager %s, status %s, manager_name %s" % \
+                    (self.name, self.status, self.manager_name)
 class Company(object):
     def __init__(self, **kwargs):
         for key, value in kwargs.iteritems():
@@ -56,30 +61,43 @@ class Company(object):
         return "Company %s" % self.name
 
 
-person_mapper = mapper(Person, people, polymorphic_on=people.c.type, polymorphic_identity='person')
-mapper(Engineer, engineers, inherits=person_mapper, polymorphic_identity='engineer')
-mapper(Manager, managers, inherits=person_mapper, polymorphic_identity='manager')
+person_mapper = mapper(Person, people, polymorphic_on=people.c.type,
+                       polymorphic_identity='person')
+mapper(Engineer, engineers, inherits=person_mapper,
+       polymorphic_identity='engineer')
+mapper(Manager, managers, inherits=person_mapper,
+       polymorphic_identity='manager')
+
+mapper(Company, companies, properties={'employees'
+       : relationship(Person, lazy='joined', backref='company',
+       cascade='all, delete-orphan')})
+
+engine = create_engine('sqlite://', echo=True)
+
+metadata.create_all(engine)
 
-mapper(Company, companies, properties={
-    'employees': relationship(Person, lazy='joined', backref='company', cascade="all, delete-orphan")
-})
+session = sessionmaker(engine)()
 
-session = create_session()
 c = Company(name='company1')
-c.employees.append(Manager(name='pointy haired boss', status='AAB', manager_name='manager1'))
-c.employees.append(Engineer(name='dilbert', status='BBA', engineer_name='engineer1', primary_language='java'))
+c.employees.append(Manager(name='pointy haired boss', status='AAB',
+                   manager_name='manager1'))
+c.employees.append(Engineer(name='dilbert', status='BBA',
+                   engineer_name='engineer1', primary_language='java'))
 c.employees.append(Person(name='joesmith', status='HHH'))
-c.employees.append(Engineer(name='wally', status='CGG', engineer_name='engineer2', primary_language='python'))
-c.employees.append(Manager(name='jsmith', status='ABA', manager_name='manager2'))
+c.employees.append(Engineer(name='wally', status='CGG',
+                   engineer_name='engineer2', primary_language='python'
+                   ))
+c.employees.append(Manager(name='jsmith', status='ABA',
+                   manager_name='manager2'))
 session.add(c)
 
-session.flush()
-session.expunge_all()
+session.commit()
 
 c = session.query(Company).get(1)
 for e in c.employees:
     print e, e._sa_instance_state.key, e.company
-assert sets.Set([e.name for e in c.employees]) == sets.Set(['pointy haired boss', 'dilbert', 'joesmith', 'wally', 'jsmith'])
+assert set([e.name for e in c.employees]) == set(['pointy haired boss',
+        'dilbert', 'joesmith', 'wally', 'jsmith'])
 print "\n"
 
 dilbert = session.query(Person).filter_by(name='dilbert').one()
@@ -88,14 +106,12 @@ assert dilbert is dilbert2
 
 dilbert.engineer_name = 'hes dibert!'
 
-session.flush()
-session.expunge_all()
+session.commit()
 
 c = session.query(Company).get(1)
 for e in c.employees:
     print e
 
 session.delete(c)
-session.flush()
+session.commit()
 
-metadata.drop_all()
index 29b214b2097dd7fc6934c167b151e35dff7531ea..a7883fcbff5f1cbea6e21fb319e0b9a108dfbb9d 100644 (file)
@@ -1,8 +1,8 @@
-from sqlalchemy import MetaData, Table, Column, Integer, String, ForeignKey
-from sqlalchemy.orm import mapper, relationship, create_session
+from sqlalchemy import MetaData, Table, Column, Integer, String, \
+    ForeignKey, create_engine
+from sqlalchemy.orm import mapper, relationship, sessionmaker
 
-metadata = MetaData('sqlite://')
-metadata.bind.echo = 'debug'
+metadata = MetaData()
 
 # a table to store companies
 companies = Table('companies', metadata, 
@@ -20,7 +20,6 @@ employees_table = Table('employees', metadata,
     Column('manager_name', String(50))
 )
 
-metadata.create_all()
 
 class Person(object):
     def __init__(self, **kwargs):
@@ -30,10 +29,14 @@ class Person(object):
         return "Ordinary person %s" % self.name
 class Engineer(Person):
     def __repr__(self):
-        return "Engineer %s, status %s, engineer_name %s, primary_language %s" % (self.name, self.status, self.engineer_name, self.primary_language)
+        return "Engineer %s, status %s, engineer_name %s, "\
+                    "primary_language %s" % \
+                        (self.name, self.status, 
+                        self.engineer_name, self.primary_language)
 class Manager(Person):
     def __repr__(self):
-        return "Manager %s, status %s, manager_name %s" % (self.name, self.status, self.manager_name)
+        return "Manager %s, status %s, manager_name %s" % \
+                    (self.name, self.status, self.manager_name)
 class Company(object):
     def __init__(self, **kwargs):
         for key, value in kwargs.iteritems():
@@ -41,25 +44,38 @@ class Company(object):
     def __repr__(self):
         return "Company %s" % self.name
 
-person_mapper = mapper(Person, employees_table, polymorphic_on=employees_table.c.type, polymorphic_identity='person')
-manager_mapper = mapper(Manager, inherits=person_mapper, polymorphic_identity='manager')
-engineer_mapper = mapper(Engineer, inherits=person_mapper, polymorphic_identity='engineer')
+person_mapper = mapper(Person, employees_table,
+                       polymorphic_on=employees_table.c.type,
+                       polymorphic_identity='person')
+manager_mapper = mapper(Manager, inherits=person_mapper,
+                        polymorphic_identity='manager')
+engineer_mapper = mapper(Engineer, inherits=person_mapper,
+                         polymorphic_identity='engineer')
 
 mapper(Company, companies, properties={
     'employees': relationship(Person, lazy=True, backref='company')
 })
 
-session = create_session()
+
+engine = create_engine('sqlite:///', echo=True)
+
+metadata.create_all(engine)
+
+session = sessionmaker(engine)()
+
 c = Company(name='company1')
-c.employees.append(Manager(name='pointy haired boss', status='AAB', manager_name='manager1'))
-c.employees.append(Engineer(name='dilbert', status='BBA', engineer_name='engineer1', primary_language='java'))
+c.employees.append(Manager(name='pointy haired boss', status='AAB',
+                   manager_name='manager1'))
+c.employees.append(Engineer(name='dilbert', status='BBA',
+                   engineer_name='engineer1', primary_language='java'))
 c.employees.append(Person(name='joesmith', status='HHH'))
-c.employees.append(Engineer(name='wally', status='CGG', engineer_name='engineer2', primary_language='python'))
-c.employees.append(Manager(name='jsmith', status='ABA', manager_name='manager2'))
+c.employees.append(Engineer(name='wally', status='CGG',
+                   engineer_name='engineer2', primary_language='python'
+                   ))
+c.employees.append(Manager(name='jsmith', status='ABA',
+                   manager_name='manager2'))
 session.add(c)
-session.flush()
-
-session.expunge_all()
+session.commit()
 
 c = session.query(Company).get(1)
 for e in c.employees:
@@ -81,6 +97,4 @@ for e in c.employees:
     print e
 
 session.delete(c)
-session.flush()
-
-metadata.drop_all()
+session.commit()
index ecdc403e75bb1ae7d6b6418579c6c45bcfa49bce..1854bfa3d8463529eb8fa284b1bf2e5c2e18c94d 100644 (file)
@@ -1,28 +1,29 @@
 """
 "polymorphic" associations, ala ActiveRecord.
 
-In this example, we are specifically targeting this ActiveRecord functionality:
+In this example, we are specifically targeting this ActiveRecord
+functionality:
 
 http://wiki.rubyonrails.org/rails/pages/UnderstandingPolymorphicAssociations
 
-The term "polymorphic" here means "object X can be referenced by objects A, B, and C,
-along a common line of association".
+The term "polymorphic" here means "object X can be referenced by objects A, B,
+and C, along a common line of association".
 
-In this example we illustrate the relationship in both directions.
-A little bit of property magic is used to smooth the edges.
+In this example we illustrate the relationship in both directions. A little
+bit of property magic is used to smooth the edges.
 
-AR creates this relationship in such a way that disallows
-any foreign key constraint from existing on the association.
-For a different way of doing this,  see
-poly_assoc_fks.py.  The interface is the same, the efficiency is more or less the same,
-but foreign key constraints may be used.  That example also better separates
-the associated target object from those which associate with it.
+AR creates this relationship in such a way that disallows any foreign key
+constraint from existing on the association. For a different way of doing
+this, see poly_assoc_fks.py. The interface is the same, the efficiency is more
+or less the same, but foreign key constraints may be used. That example also
+better separates the associated target object from those which associate with
+it.
 
 """
 
 from sqlalchemy import MetaData, Table, Column, Integer, String, and_
-from sqlalchemy.orm import (mapper, relationship, create_session, class_mapper,
-    backref)
+from sqlalchemy.orm import mapper, relationship, sessionmaker, \
+    class_mapper, backref
 
 metadata = MetaData('sqlite://')
 
@@ -41,12 +42,15 @@ addresses = Table("addresses", metadata,
 class Address(object):
     def __init__(self, type):
         self.addressable_type = type
-    member = property(lambda self: getattr(self, '_backref_%s' % self.addressable_type))
+    @property
+    def member(self):
+        return getattr(self, '_backref_%s' % self.addressable_type)
 
 def addressable(cls, name, uselist=True):
     """addressable 'interface'.
 
-    if you really wanted to make a "generic" version of this function, it's straightforward.
+    if you really wanted to make a "generic" version of this function, it's
+    straightforward.
     """
 
     # create_address function, imitaes the rails example.
@@ -71,8 +75,13 @@ def addressable(cls, name, uselist=True):
     foreign_keys = [addresses.c.addressable_id]
     mapper.add_property(name, relationship(
             Address,
-            primaryjoin=primaryjoin, uselist=uselist, foreign_keys=foreign_keys,
-            backref=backref('_backref_%s' % table.name, primaryjoin=list(table.primary_key)[0] == addresses.c.addressable_id, foreign_keys=foreign_keys)
+            primaryjoin=primaryjoin, 
+            uselist=uselist, 
+            foreign_keys=foreign_keys,
+            backref=backref('_backref_%s' % table.name, 
+                            primaryjoin=list(table.primary_key)[0] ==\
+                                        addresses.c.addressable_id, 
+                            foreign_keys=foreign_keys)
         )
     )
 
@@ -124,12 +133,11 @@ a2.street = '345 orchard ave'
 a3 = o1.create_address()
 a3.street = '444 park ave.'
 
-sess = create_session()
+sess = sessionmaker()()
 sess.add(u1)
 sess.add(o1)
-sess.flush()
 
-sess.expunge_all()
+sess.commit()
 
 # query objects, get their addresses
 
index 96c9935c30aaf713b9d8bb6001a70c17876356ae..a22020e08865b71826bb3f630306b38343b9d7e7 100644 (file)
@@ -1,26 +1,26 @@
 """
 "polymorphic" associations, ala SQLAlchemy.
 
-See "poly_assoc.py" for an imitation of this functionality as implemented
-in ActiveRecord.
-
-Here, we build off the previous example, adding an association table
-that allows the relationship to be expressed as a many-to-one from the
-"model" object to its "association", so that each model table bears the foreign
-key constraint.  This allows the same functionality via traditional
-normalized form with full constraints.  It also isolates the target
-associated object from its method of being associated, allowing greater
-flexibility in its usage.
-
-As in the previous example, a little bit of property magic is used
-to smooth the edges.
-
-For a more genericized version of this example, see
-poly_assoc_generic.py.
+See "poly_assoc.py" for an imitation of this functionality as implemented in
+ActiveRecord.
+
+Here, we build off the previous example, adding an association table that
+allows the relationship to be expressed as a many-to-one from the "model"
+object to its "association", so that each model table bears the foreign key
+constraint. This allows the same functionality via traditional normalized form
+with full constraints. It also isolates the target associated object from its
+method of being associated, allowing greater flexibility in its usage.
+
+As in the previous example, a little bit of property magic is used to smooth
+the edges.
+
+For a more genericized version of this example, see poly_assoc_generic.py.
 """
 
-from sqlalchemy import MetaData, Table, Column, Integer, String, ForeignKey
-from sqlalchemy.orm import mapper, relationship, create_session, class_mapper
+from sqlalchemy import MetaData, Table, Column, Integer, String, \
+    ForeignKey
+from sqlalchemy.orm import mapper, relationship, sessionmaker, \
+    class_mapper
 
 metadata = MetaData('sqlite://')
 
@@ -42,7 +42,11 @@ address_associations = Table("address_associations", metadata,
 )
 
 class Address(object):
-    member = property(lambda self: getattr(self.association, '_backref_%s' % self.association.type))
+
+    @property
+    def member(self):
+        return getattr(self.association, '_backref_%s'
+                       % self.association.type)
 
 class AddressAssoc(object):
     def __init__(self, name):
@@ -56,7 +60,10 @@ def addressable(cls, name, uselist=True):
     """
     mapper = class_mapper(cls)
     table = mapper.local_table
-    mapper.add_property('address_rel', relationship(AddressAssoc, backref='_backref_%s' % table.name))
+    mapper.add_property('address_rel', 
+                        relationship(AddressAssoc, 
+                                backref='_backref_%s' % table.name)
+                        )
 
     if uselist:
         # list based property decorator
@@ -88,7 +95,7 @@ users = Table("users", metadata,
     Column('id', Integer, primary_key=True),
     Column('name', String(50), nullable=False),
     # this column ties the users table into the address association
-    Column('assoc_id', None, ForeignKey('address_associations.assoc_id'))
+    Column('assoc_id', Integer, ForeignKey('address_associations.assoc_id'))
     )
 
 class User(object):
@@ -104,7 +111,7 @@ orders = Table("orders", metadata,
     Column('id', Integer, primary_key=True),
     Column('description', String(50), nullable=False),
     # this column ties the orders table into the address association
-    Column('assoc_id', None, ForeignKey('address_associations.assoc_id'))
+    Column('assoc_id', Integer, ForeignKey('address_associations.assoc_id'))
     )
 
 class Order(object):
@@ -136,17 +143,17 @@ a2.street = '345 orchard ave'
 o1.address = Address()
 o1.address.street = '444 park ave.'
 
-sess = create_session()
+sess = sessionmaker()()
 sess.add(u1)
 sess.add(o1)
-sess.flush()
 
-sess.expunge_all()
+sess.commit()
 
 # query objects, get their addresses
 
 bob = sess.query(User).filter_by(name='bob').one()
-assert [s.street for s in bob.addresses] == ['123 anywhere street', '345 orchard ave']
+assert [s.street for s in bob.addresses] == \
+            ['123 anywhere street', '345 orchard ave']
 
 order = sess.query(Order).filter_by(description='order 1').one()
 assert order.address.street == '444 park ave.'
index 235c21becc702985375de645c8f8d45661b5202f..aaa182df0a78c28b4c38647056241d5ae6b508ac 100644 (file)
@@ -1,13 +1,14 @@
 """
 "polymorphic" associations, ala SQLAlchemy.
 
-This example generalizes the function in poly_assoc_pk.py into a
-function "association" which creates a new polymorphic association
-"interface".
+This example generalizes the function in poly_assoc_pk.py into a function
+"association" which creates a new polymorphic association "interface".
 """
 
-from sqlalchemy import MetaData, Table, Column, Integer, String, ForeignKey
-from sqlalchemy.orm import mapper, relationship, create_session, class_mapper
+from sqlalchemy import MetaData, Table, Column, Integer, String, \
+    ForeignKey
+from sqlalchemy.orm import mapper, relationship, sessionmaker, \
+    class_mapper
 
 metadata = MetaData('sqlite://')
 
@@ -31,7 +32,10 @@ def association(cls, table):
 
         mapper = class_mapper(cls)
         table = mapper.local_table
-        mapper.add_property(attr_name, relationship(GenericAssoc, backref='_backref_%s' % table.name))
+        mapper.add_property(attr_name, 
+                            relationship(GenericAssoc, 
+                                    backref='_backref_%s' % table.name)
+                            )
 
         if uselist:
             # list based property decorator
@@ -49,8 +53,13 @@ def association(cls, table):
                     setattr(self, attr_name, GenericAssoc(table.name))
                 getattr(self, attr_name).targets = [value]
             setattr(cls, name, property(get, set))
-
-    setattr(cls, 'member', property(lambda self: getattr(self.association, '_backref_%s' % self.association.type)))
+    
+    @property
+    def member(self):
+        return getattr(self.association, 
+                    '_backref_%s' % self.association.type)
+        
+    setattr(cls, 'member', member)
 
     mapper(GenericAssoc, association_table, properties={
         'targets':relationship(cls, backref='association'),
@@ -64,7 +73,7 @@ def association(cls, table):
 
 addresses = Table("addresses", metadata,
     Column('id', Integer, primary_key=True),
-    Column('assoc_id', None, ForeignKey('addresses_associations.assoc_id')),
+    Column('assoc_id', Integer, ForeignKey('addresses_associations.assoc_id')),
     Column('street', String(100)),
     Column('city', String(50)),
     Column('country', String(50))
@@ -85,7 +94,7 @@ mapper(Address, addresses)
 users = Table("users", metadata,
     Column('id', Integer, primary_key=True),
     Column('name', String(50), nullable=False),
-    Column('assoc_id', None, ForeignKey('addresses_associations.assoc_id'))
+    Column('assoc_id', Integer, ForeignKey('addresses_associations.assoc_id'))
     )
 
 class User(object):
@@ -102,7 +111,7 @@ addressable(User, 'addresses', uselist=True)
 orders = Table("orders", metadata,
     Column('id', Integer, primary_key=True),
     Column('description', String(50), nullable=False),
-    Column('assoc_id', None, ForeignKey('addresses_associations.assoc_id'))
+    Column('assoc_id', Integer, ForeignKey('addresses_associations.assoc_id'))
     )
 
 class Order(object):
@@ -132,17 +141,16 @@ a2.street = '345 orchard ave'
 o1.address = Address()
 o1.address.street = '444 park ave.'
 
-sess = create_session()
+sess = sessionmaker()()
 sess.add(u1)
 sess.add(o1)
-sess.flush()
-
-sess.expunge_all()
+sess.commit()
 
 # query objects, get their addresses
 
 bob = sess.query(User).filter_by(name='bob').one()
-assert [s.street for s in bob.addresses] == ['123 anywhere street', '345 orchard ave']
+assert [s.street for s in bob.addresses] == \
+            ['123 anywhere street', '345 orchard ave']
 
 order = sess.query(Order).filter_by(description='order 1').one()
 assert order.address.street == '444 park ave.'
index f0e1cf543bedcbdbc4e65dddd1ef907a85acaf70..f2f8832cf7ca12b93f7f6f1cdb68f7aaefcf6698 100644 (file)
@@ -1,7 +1,12 @@
 """
-Illustrates an extension which creates version tables for entities and stores records for each change.  The same idea as Elixir's versioned extension, but more efficient (uses attribute API to get history) and handles class inheritance.  The given extensions generate an anonymous "history" class which represents historical versions of the target object.   
+Illustrates an extension which creates version tables for entities and stores
+records for each change. The same idea as Elixir's versioned extension, but
+more efficient (uses attribute API to get history) and handles class
+inheritance. The given extensions generate an anonymous "history" class which
+represents historical versions of the target object.
 
-Usage is illustrated via a unit test module ``test_versioning.py``, which can be run via nose::
+Usage is illustrated via a unit test module ``test_versioning.py``, which can
+be run via nose::
 
     nosetests -w examples/versioning/
 
@@ -38,7 +43,8 @@ A fragment of example usage, using declarative::
                 all() \\
                 == [SomeClassHistory(version=1, name='sc1')]
 
-To apply ``VersionedMeta`` to a subset of classes (probably more typical), the metaclass can be applied on a per-class basis::
+To apply ``VersionedMeta`` to a subset of classes (probably more typical), the
+metaclass can be applied on a per-class basis::
 
     from history_meta import VersionedMeta, VersionedListener
 
@@ -55,7 +61,8 @@ To apply ``VersionedMeta`` to a subset of classes (probably more typical), the m
 
         # ...
 
-The ``VersionedMeta`` is a declarative metaclass - to use the extension with plain mappers, the ``_history_mapper`` function can be applied::
+The ``VersionedMeta`` is a declarative metaclass - to use the extension with
+plain mappers, the ``_history_mapper`` function can be applied::
 
     from history_meta import _history_mapper
 
index 8a916791c3ff1b64a72a2a04ee64c4c8d7f6b8d2..a7b03c5bfc324a3e21bafef7ef52cd7034cedccc 100644 (file)
@@ -13,7 +13,7 @@ def col_references_table(col, table):
 def _history_mapper(local_mapper):
     cls = local_mapper.class_
 
-    # SLIGHT SQLA HACK #1 - set the "active_history" flag
+    # set the "active_history" flag
     # on on column-mapped attributes so that the old version
     # of the info is always loaded (currently sets it on all attributes)
     for prop in local_mapper.iterate_properties:
@@ -117,7 +117,7 @@ def create_version(obj, session, deleted = False):
                 
             obj_col = om.local_table.c[hist_col.key]
 
-            # SLIGHT SQLA HACK #3 - get the value of the
+            # get the value of the
             # attribute based on the MapperProperty related to the
             # mapped column.  this will allow usage of MapperProperties
             # that have a different keyname than that of the mapped column.