]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
this definitely has to go - theres bugs in merge(), serialization which
authorMike Bayer <mike_mp@zzzcomputing.com>
Sun, 10 Jan 2010 18:29:48 +0000 (18:29 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Sun, 10 Jan 2010 18:29:48 +0000 (18:29 +0000)
prevent it from being useful.   will have a much more comprehensive example in
0.6.

examples/query_caching/per_relation.py [deleted file]

diff --git a/examples/query_caching/per_relation.py b/examples/query_caching/per_relation.py
deleted file mode 100644 (file)
index 6e0df46..0000000
+++ /dev/null
@@ -1,176 +0,0 @@
-"""
-Ready for some really powerful stuff ?
-
-We're going to use Beaker caching, and create functions that load and cache what we want, which
-can be used in any scenario.  Then we're going to associate them with many-to-one relations
-for individual queries.  
-
-Think of it as lazy loading from a long term cache.  For rarely-mutated objects, this is a super
-performing way to go.
-
-"""
-
-from sqlalchemy.orm.query import Query, _generative
-from sqlalchemy.orm.interfaces import MapperOption
-from sqlalchemy.orm.session import Session
-from sqlalchemy.sql import visitors
-
-class CachingQuery(Query):
-    """override __iter__ to pull results from a callable 
-       that might have been attached to the Query.
-        
-    """
-    def __iter__(self):
-        if hasattr(self, 'cache_callable'):
-            try:
-                ret = self.cache_callable(self)
-            except KeyError:
-                ret = list(Query.__iter__(self))
-                for x in ret:
-                    self.session.expunge(x)
-
-            return iter(self.session.merge(x, dont_load=True) for x in ret)
-
-        else:
-            return Query.__iter__(self)
-
-class FromCallable(MapperOption):
-    """A MapperOption that associates a callable with particular 'path' load.
-    
-    When a lazyload occurs, the Query has a "path" which is a tuple of
-    (mapper, key, mapper, key) indicating the path along relations from
-    the original mapper to the endpoint mapper.
-    
-    """
-    
-    propagate_to_loaders = True
-    
-    def __init__(self, key):
-        self.cls_ = key.property.parent.class_
-        self.propname = key.property.key
-    
-    def __call__(self, q):
-        raise NotImplementedError()
-        
-    def process_query(self, query):
-        if query._current_path:
-            mapper, key = query._current_path[-2:]
-            if mapper.class_ is self.cls_ and key == self.propname:
-                query.cache_callable = self
-
-def params_from_query(query):
-    """Pull the bind parameter values from a query.
-    
-    This takes into account any scalar attribute bindparam set up.
-    
-    E.g. params_from_query(query.filter(Cls.foo==5).filter(Cls.bar==7)))
-    would return [5, 7].
-    
-    
-    """
-    
-    v = []
-    def visit_bindparam(bind):
-        value = query._params.get(bind.key, bind.value)
-        v.append(value)
-    visitors.traverse(query._criterion, {}, {'bindparam':visit_bindparam})
-    return v
-                
-if __name__ == '__main__':
-    """Usage example.  We'll use Beaker to set up a region and then a short def
-    that loads a 'Widget' object by id.
-    
-    """
-    from sqlalchemy.orm import sessionmaker, scoped_session
-    from sqlalchemy import create_engine
-    
-    # beaker 1.4 or above
-    from beaker.cache import CacheManager 
-
-    # sample CacheManager.   In reality, use memcached.   (seriously, don't bother
-    # with any other backend.)
-    cache_manager = CacheManager(
-                        cache_regions={
-                            'default_region':{'type':'memory','expire':3600}
-                        }
-                    )
-
-    # SQLA configuration
-    engine=create_engine('sqlite://', echo=True)
-    Session = scoped_session(sessionmaker(query_cls=CachingQuery, bind=engine))
-    
-    from sqlalchemy import Column, Integer, String, ForeignKey
-    from sqlalchemy.orm import relation
-    from sqlalchemy.ext.declarative import declarative_base
-
-    # mappings
-    Base = declarative_base()
-    
-    class User(Base):
-        __tablename__ = 'user'
-        id = Column(Integer, primary_key=True)
-        name = Column(String(100))
-        widget_id = Column(Integer, ForeignKey('widget.id'))
-        
-        widget = relation("Widget")
-
-    class Widget(Base):
-        __tablename__ = 'widget'
-        id = Column(Integer, primary_key=True)
-        name = Column(String(100))
-
-    # Widget loading.
-    
-    @cache_manager.region('default_region', 'byid')
-    def load_widget(widget_id):
-        """Load a widget by id, caching the result in Beaker."""
-        
-        return Session.query(Widget).filter(Widget.id==widget_id).first()
-
-    class CachedWidget(FromCallable):
-        """A MapperOption that will pull user widget links from Beaker.
-        
-        We build a subclass of FromCallable with a __call__ method
-        so that the option itself is pickleable.
-        
-        """
-        def __call__(self, q):
-            return [load_widget(*params_from_query(q))]
-
-    Base.metadata.create_all(engine)
-    
-    sess = Session()
-    
-    # create data.
-    w1 = Widget(name='w1')
-    w2 = Widget(name='w2')
-    sess.add_all(
-        [User(name='u1', widget=w1), User(name='u2', widget=w1), User(name='u3', widget=w2)]
-    )
-    sess.commit()
-    
-    # call load_widget with 1 and 2.  this will cache those widget objects in beaker.
-    w1 = load_widget(1)
-    w2 = load_widget(2)
-
-    # clear session entirely.
-    sess.expunge_all()
-    
-    # load users, sending over our option.
-    u1, u2, u3 = sess.query(User).options(CachedWidget(User.widget)).order_by(User.id).all()
-    
-    print "------------------------"
-
-    # access the "Widget".   No SQL occurs below this line !
-    assert u1.widget.name == 'w1'
-
-    # access the same "Widget" on u2.  Local w1 is reused, no extra cache roundtrip !
-    assert u2.widget.name == 'w1'
-    assert u2.widget is u1.widget
-    
-    assert u3.widget.name == 'w2'
-
-    # user + the option (embedded in its state)
-    # are pickleable themselves (important for further caching)
-    import pickle
-    assert pickle.dumps(u1)
\ No newline at end of file