summaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2008-10-24 19:41:25 +0000
committerMike Bayer <mike_mp@zzzcomputing.com>2008-10-24 19:41:25 +0000
commiteba763b2588987224c6313b4d1c9f8feec616c1d (patch)
tree9e108798e6e8342ba090de3dde9a6dd6f3dd296d /examples
parentecf22b390b3d3b44d6094ee0355748b4d163fccb (diff)
downloadsqlalchemy-eba763b2588987224c6313b4d1c9f8feec616c1d.tar.gz
two more cache examples
Diffstat (limited to 'examples')
-rw-r--r--examples/query_caching/implicit.py70
-rw-r--r--examples/query_caching/per_session.py73
-rw-r--r--examples/query_caching/query_caching.py5
3 files changed, 145 insertions, 3 deletions
diff --git a/examples/query_caching/implicit.py b/examples/query_caching/implicit.py
new file mode 100644
index 000000000..15a6d121a
--- /dev/null
+++ b/examples/query_caching/implicit.py
@@ -0,0 +1,70 @@
+"""Example of caching objects in a per-session cache,
+including implicit usage of the statement and params as a key.
+
+"""
+from sqlalchemy.orm.query import Query
+from sqlalchemy.orm.session import Session
+
+class CachingQuery(Query):
+
+ # single point of object loading is __iter__(). objects in the cache are not associated
+ # with a session and are never returned directly; only merged copies.
+ def __iter__(self):
+ try:
+ cache = self.session._cache
+ except AttributeError:
+ self.session._cache = cache = {}
+
+ stmt = self.statement.compile()
+ params = stmt.params
+ params.update(self._params)
+ cachekey = str(stmt) + str(params)
+
+ try:
+ ret = cache[cachekey]
+ except KeyError:
+ ret = list(Query.__iter__(self))
+ cache[cachekey] = ret
+
+ return iter(ret)
+
+
+# example usage
+if __name__ == '__main__':
+ from sqlalchemy import Column, create_engine, Integer, String
+ from sqlalchemy.orm import sessionmaker
+ from sqlalchemy.ext.declarative import declarative_base
+
+ Session = sessionmaker(query_cls=CachingQuery)
+
+ Base = declarative_base(engine=create_engine('sqlite://', echo=True))
+
+ class User(Base):
+ __tablename__ = 'users'
+ id = Column(Integer, primary_key=True)
+ name = Column(String(100))
+
+ def __repr__(self):
+ return "User(name=%r)" % self.name
+
+ Base.metadata.create_all()
+
+ sess = Session()
+
+ sess.add_all(
+ [User(name='u1'), User(name='u2'), User(name='u3')]
+ )
+ sess.commit()
+
+ # issue a query
+ print sess.query(User).filter(User.name.in_(['u2', 'u3'])).all()
+
+ # issue another
+ print sess.query(User).filter(User.name == 'u1').all()
+
+ # pull straight from cache
+ print sess.query(User).filter(User.name.in_(['u2', 'u3'])).all()
+
+ print sess.query(User).filter(User.name == 'u1').all()
+
+
diff --git a/examples/query_caching/per_session.py b/examples/query_caching/per_session.py
new file mode 100644
index 000000000..12684082c
--- /dev/null
+++ b/examples/query_caching/per_session.py
@@ -0,0 +1,73 @@
+"""Example of caching objects in a per-session cache.
+
+
+This approach is faster in that objects don't need to be detached/remerged
+between sessions, but is slower in that the cache is empty at the start
+of each session's lifespan.
+
+"""
+
+from sqlalchemy.orm.query import Query, _generative
+from sqlalchemy.orm.session import Session
+
+class CachingQuery(Query):
+
+ # generative method to set a "cache" key. The method of "keying" the cache
+ # here can be made more sophisticated, such as caching based on the query._criterion.
+ @_generative()
+ def with_cache_key(self, cachekey):
+ self.cachekey = cachekey
+
+ # single point of object loading is __iter__(). objects in the cache are not associated
+ # with a session and are never returned directly; only merged copies.
+ def __iter__(self):
+ if hasattr(self, 'cachekey'):
+ try:
+ cache = self.session._cache
+ except AttributeError:
+ self.session._cache = cache = {}
+
+ try:
+ ret = cache[self.cachekey]
+ except KeyError:
+ ret = list(Query.__iter__(self))
+ cache[self.cachekey] = ret
+
+ return iter(ret)
+
+ else:
+ return Query.__iter__(self)
+
+# example usage
+if __name__ == '__main__':
+ from sqlalchemy import Column, create_engine, Integer, String
+ from sqlalchemy.orm import sessionmaker
+ from sqlalchemy.ext.declarative import declarative_base
+
+ Session = sessionmaker(query_cls=CachingQuery)
+
+ Base = declarative_base(engine=create_engine('sqlite://', echo=True))
+
+ class User(Base):
+ __tablename__ = 'users'
+ id = Column(Integer, primary_key=True)
+ name = Column(String(100))
+
+ def __repr__(self):
+ return "User(name=%r)" % self.name
+
+ Base.metadata.create_all()
+
+ sess = Session()
+
+ sess.add_all(
+ [User(name='u1'), User(name='u2'), User(name='u3')]
+ )
+ sess.commit()
+
+ # cache two user objects
+ sess.query(User).with_cache_key('u2andu3').filter(User.name.in_(['u2', 'u3'])).all()
+
+ # pull straight from cache
+ print sess.query(User).with_cache_key('u2andu3').all()
+
diff --git a/examples/query_caching/query_caching.py b/examples/query_caching/query_caching.py
index 70dc6683c..92d48e2d7 100644
--- a/examples/query_caching/query_caching.py
+++ b/examples/query_caching/query_caching.py
@@ -1,3 +1,5 @@
+"""Example of caching objects in a global cache."""
+
from sqlalchemy.orm.query import Query, _generative
from sqlalchemy.orm.session import Session
@@ -67,6 +69,3 @@ if __name__ == '__main__':
# pull straight from cache
print sess.query(User).with_cache_key('u2andu3').all()
-
-
-