summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2010-01-18 20:58:34 +0000
committerMike Bayer <mike_mp@zzzcomputing.com>2010-01-18 20:58:34 +0000
commit8a9e2a6c3783433c6b1c7c6a3d6ffd2cc7c1fd16 (patch)
tree17e8531ec6a46d33fb9fe5fb931e045d36647e40
parent9680e6483f4a811e147dd75bf3f5ccab989f01e0 (diff)
downloadsqlalchemy-8a9e2a6c3783433c6b1c7c6a3d6ffd2cc7c1fd16.tar.gz
updated the large_collection example to modern SQLA.
-rw-r--r--examples/README2
-rw-r--r--examples/collections/large_collection.py93
-rw-r--r--examples/large_collection/__init__.py (renamed from examples/collections/__init__.py)0
-rw-r--r--examples/large_collection/large_collection.py100
4 files changed, 100 insertions, 95 deletions
diff --git a/examples/README b/examples/README
deleted file mode 100644
index bb4b95335..000000000
--- a/examples/README
+++ /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
index 2451ea582..000000000
--- a/examples/collections/large_collection.py
+++ /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/collections/__init__.py b/examples/large_collection/__init__.py
index e69de29bb..e69de29bb 100644
--- a/examples/collections/__init__.py
+++ b/examples/large_collection/__init__.py
diff --git a/examples/large_collection/large_collection.py b/examples/large_collection/large_collection.py
new file mode 100644
index 000000000..4d98eed2b
--- /dev/null
+++ b/examples/large_collection/large_collection.py
@@ -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