From: Mike Bayer Date: Tue, 12 Dec 2006 21:42:13 +0000 (+0000) Subject: new collections example X-Git-Tag: rel_0_3_3~6 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ee99f8d58cd283a9557631cdaefddebc7549a6c4;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git new collections example --- diff --git a/examples/collections/large_collection.py b/examples/collections/large_collection.py new file mode 100644 index 0000000000..ea0dd236ee --- /dev/null +++ b/examples/collections/large_collection.py @@ -0,0 +1,84 @@ +"""illlustrates techniques for dealing with very large collections""" + +from sqlalchemy import * +meta = BoundMetaData('sqlite://', echo=True) + +org_table = Table('organizations', meta, + Column('org_id', Integer, primary_key=True), + Column('org_name', String(50), nullable=False, key='name')) + +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'))) +meta.create_all() + +class Organization(object): + def __init__(self, name): + self.name = name + def find_members(self, criterion): + """locate a subset of the members associated with this Organization""" + return object_session(self).query(Member).select(and_(member_table.c.name.like(criterion), org_table.c.org_id==self.org_id), from_obj=[org_table.join(member_table)]) + +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.save(org) + +print "-------------------------\nflush one - save org + 3 members" +sess.flush() +sess.clear() + +# reload. load the org and some child members +print "-------------------------\nload subset of members" +org = sess.query(Organization).get(org.org_id) +members = org.find_members('%member t%') +print members + +sess.clear() + + +# 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.clear() +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() +