]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
updated the large_collection example to modern SQLA.
authorMike Bayer <mike_mp@zzzcomputing.com>
Mon, 18 Jan 2010 20:58:34 +0000 (20:58 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Mon, 18 Jan 2010 20:58:34 +0000 (20:58 +0000)
examples/README [deleted file]
examples/collections/large_collection.py [deleted file]
examples/large_collection/__init__.py [moved from examples/collections/__init__.py with 100% similarity]
examples/large_collection/large_collection.py [new file with mode: 0644]

diff --git a/examples/README b/examples/README
deleted file mode 100644 (file)
index bb4b953..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-placeholder
-
diff --git a/examples/collections/large_collection.py b/examples/collections/large_collection.py
deleted file mode 100644 (file)
index 2451ea5..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-"""illlustrates techniques for dealing with very large collections.
-
-Also see the docs regarding the new "dynamic" relation option, which 
-presents a more refined version of some of these patterns.
-"""
-
-from sqlalchemy import MetaData, Table, Column, Integer, String, ForeignKey
-from sqlalchemy.orm import (mapper, relation, create_session, MapperExtension,
-    object_session)
-
-meta = MetaData('sqlite://')
-meta.bind.echo = True
-
-org_table = Table('organizations', meta, 
-    Column('org_id', Integer, primary_key=True),
-    Column('org_name', String(50), nullable=False, key='name'),
-    mysql_engine='InnoDB')
-    
-member_table = Table('members', meta,
-    Column('member_id', Integer, primary_key=True),
-    Column('member_name', String(50), nullable=False, key='name'),
-    Column('org_id', Integer, ForeignKey('organizations.org_id')), 
-    mysql_engine='InnoDB')
-meta.create_all()    
-    
-class Organization(object):
-    def __init__(self, name):
-        self.name = name
-    member_query = property(lambda self:object_session(self).query(Member).with_parent(self), 
-        doc="""locate a subset of the members associated with this Organization""")
-    
-class Member(object):
-    def __init__(self, name):
-        self.name = name
-
-# note that we can also place "ON DELETE CASCADE" on the tables themselves,
-# instead of using this extension
-class DeleteMemberExt(MapperExtension):
-    """will delete child Member objects in one pass when Organizations are deleted"""
-    def before_delete(self, mapper, connection, instance):
-        connection.execute(member_table.delete(member_table.c.org_id==instance.org_id))
-
-mapper(Organization, org_table, extension=DeleteMemberExt(), properties = {
-    # set up the relationship with "lazy=None" so no loading occurs (even lazily),
-    # "cascade='all, delete-orphan'" to declare Member objects as local to their parent Organization,
-    # "passive_deletes=True" so that the "delete, delete-orphan" cascades do not load in the child objects
-    # upon deletion
-    'members' : relation(Member, lazy=None, passive_deletes=True, cascade="all, delete-orphan")
-})
-
-mapper(Member, member_table)
-
-sess = create_session()
-
-# create org with some members
-org = Organization('org one')
-org.members.append(Member('member one'))
-org.members.append(Member('member two'))
-org.members.append(Member('member three'))
-
-sess.add(org)
-
-print "-------------------------\nflush one - save org + 3 members"
-sess.flush()
-sess.expunge_all()
-
-# reload. load the org and some child members
-print "-------------------------\nload subset of members"
-org = sess.query(Organization).get(org.org_id)
-members = org.member_query.filter(member_table.c.name.like('%member t%')).all()
-print members
-
-sess.expunge_all()
-
-
-# reload.  create some more members and flush, without loading any of the original members
-org = sess.query(Organization).get(org.org_id)
-org.members.append(Member('member four'))
-org.members.append(Member('member five'))
-org.members.append(Member('member six'))
-
-print "-------------------------\nflush two - save 3 more members"
-sess.flush()
-
-sess.expunge_all()
-org = sess.query(Organization).get(org.org_id)
-
-# now delete.  note that this will explictily delete members four, five and six because they are in the session,
-# but will not issue individual deletes for members one, two and three, nor will it load them.
-sess.delete(org)
-print "-------------------------\nflush three - delete org, delete members in one statement"
-sess.flush()
-
diff --git a/examples/large_collection/large_collection.py b/examples/large_collection/large_collection.py
new file mode 100644 (file)
index 0000000..4d98eed
--- /dev/null
@@ -0,0 +1,100 @@
+"""Large collection example.
+
+Illustrates the options to use on relation() when the list of related objects
+is very large.
+
+"""
+
+from sqlalchemy import (MetaData, Table, Column, Integer, String, ForeignKey,
+                        create_engine)
+from sqlalchemy.orm import (mapper, relation, sessionmaker)
+
+
+meta = MetaData()
+
+org_table = Table('organizations', meta, 
+    Column('org_id', Integer, primary_key=True),
+    Column('org_name', String(50), nullable=False, key='name'),
+    mysql_engine='InnoDB')
+    
+member_table = Table('members', meta,
+    Column('member_id', Integer, primary_key=True),
+    Column('member_name', String(50), nullable=False, key='name'),
+    Column('org_id', Integer, ForeignKey('organizations.org_id', ondelete="CASCADE")),
+    mysql_engine='InnoDB')
+    
+    
+class Organization(object):
+    def __init__(self, name):
+        self.name = name
+    
+class Member(object):
+    def __init__(self, name):
+        self.name = name
+
+mapper(Organization, org_table, properties = {
+    'members' : relation(Member, 
+        # Organization.members will be a Query object - no loading
+        # of the entire collection occurs unless requested
+        lazy="dynamic", 
+        
+        # Member objects "belong" to their parent, are deleted when 
+        # removed from the collection
+        cascade="all, delete-orphan",
+        
+        # "delete, delete-orphan" cascade does not load in objects on delete,
+        # allows ON DELETE CASCADE to handle it.
+        # this only works with a database that supports ON DELETE CASCADE - 
+        # *not* sqlite or MySQL with MyISAM
+        passive_deletes=True, 
+    )
+})
+
+mapper(Member, member_table)
+
+if __name__ == '__main__':
+    engine = create_engine("mysql://scott:tiger@localhost/test", echo=True)
+    meta.create_all(engine)
+    
+    # expire_on_commit=False means the session contents
+    # will not get invalidated after commit.
+    sess = sessionmaker(engine, expire_on_commit=False)()
+
+    # create org with some members
+    org = Organization('org one')
+    org.members.append(Member('member one'))
+    org.members.append(Member('member two'))
+    org.members.append(Member('member three'))
+
+    sess.add(org)
+
+    print "-------------------------\nflush one - save org + 3 members\n"
+    sess.commit()
+
+    # the 'members' collection is a Query.  it issues 
+    # SQL as needed to load subsets of the collection.
+    print "-------------------------\nload subset of members\n"
+    members = org.members.filter(member_table.c.name.like('%member t%')).all()
+    print members
+
+    # new Members can be appended without any
+    # SQL being emitted to load the full collection
+    org.members.append(Member('member four'))
+    org.members.append(Member('member five'))
+    org.members.append(Member('member six'))
+
+    print "-------------------------\nflush two - save 3 more members\n"
+    sess.commit()
+
+    # delete the object.   Using ON DELETE CASCADE 
+    # SQL is only emitted for the head row - the Member rows 
+    # disappear automatically without the need for additional SQL.
+    sess.delete(org)
+    print "-------------------------\nflush three - delete org, delete members in one statement\n"
+    sess.commit()
+    
+    print "-------------------------\nno Member rows should remain:\n"
+    print sess.query(Member).count()
+    
+    print "------------------------\ndone.  dropping tables."
+    meta.drop_all(engine)
\ No newline at end of file