abo*_*lov 1 python sqlalchemy dogpile.cache
我有三个具有继承和关系的模型,我想将查询缓存到这个模型。
class Person(Base):
__tablename__ = 'person'
id = Column(Integer, primary_key=True)
name = Column(String(100), nullable=False)
type = Column(String(50))
__mapper_args__ = {
'polymorphic_identity': 'object',
'polymorphic_on': type
}
class Man(Person):
__tablename__ = 'man'
id = Column(Integer, ForeignKey('person.id'), primary_key=True)
age = Column(String(100), nullable=False)
__mapper_args__ = {'polymorphic_identity': 'man'}
class Config(Base):
__tablename__ = "config"
id = Column(Integer, primary_key=True)
person = Column(Integer, ForeignKey('person.id'))
address = Column(String)
person_ref = relationship(Person)
Run Code Online (Sandbox Code Playgroud)
还有很多从Personal继承的其他模型。例如,我需要通过Config关系访问Man属性。通常我会这样做:
config = session.query(Config).join(Config.person_ref).filter(Person.type == 'man').first()
print config.person_ref.age
Run Code Online (Sandbox Code Playgroud)
如何使用 dogpile 缓存这样的查询?我可以将查询缓存到Config,但我不能将查询缓存到Man 的属性,每次都发出 SQL。我尝试使用with_polymorphic,但它只能在没有joinedload 的情况下工作。(不明白为什么)
config = session.query(Config).options(FromCache("default")).first()
people = session.query(Person).options(FromCache("default")).with_polymorphic('*').get(config.person)
Run Code Online (Sandbox Code Playgroud)
但我需要joinload来过滤类型。
为了确保加载“man”表,of_type() 可用于任何子类型模式。我们可以改为使用 with_polymorphic() 加入一个完整的多态可选。有关详细信息,请参阅http://docs.sqlalchemy.org/en/latest/orm/inheritance.html#creating-joins-to-specific-subtypes 中的示例。只要您想要的数据出现在一个 SELECT 查询中,那么该数据就会在通过 FromCache 缓存的数据中。确实,缓存配方目前不包括一个系统,通过该系统可以在事后缓存附加加入的继承属性的延迟加载。
from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.declarative import declarative_base
from examples.dogpile_caching.caching_query import query_callable, FromCache, RelationshipCache
from hashlib import md5
from dogpile.cache.region import make_region
Base = declarative_base()
class Person(Base):
__tablename__ = 'person'
id = Column(Integer, primary_key=True)
name = Column(String(100), nullable=False)
type = Column(String(50))
__mapper_args__ = {
'polymorphic_identity': 'object',
'polymorphic_on': type
}
class Man(Person):
__tablename__ = 'man'
id = Column(Integer, ForeignKey('person.id'), primary_key=True)
age = Column(String(100), nullable=False)
__mapper_args__ = {'polymorphic_identity': 'man'}
class SomethingElse(Person):
__tablename__ = 'somethingelse'
id = Column(Integer, ForeignKey('person.id'), primary_key=True)
age = Column(String(100), nullable=False)
__mapper_args__ = {'polymorphic_identity': 'somethingelse'}
class Config(Base):
__tablename__ = "config"
id = Column(Integer, primary_key=True)
person = Column(Integer, ForeignKey('person.id'))
address = Column(String)
person_ref = relationship(Person)
e = create_engine("sqlite://", echo=True)
Base.metadata.create_all(e)
def md5_key_mangler(key):
"""Receive cache keys as long concatenated strings;
distill them into an md5 hash.
"""
return md5(key.encode('ascii')).hexdigest()
regions = {}
regions['default'] = make_region(
key_mangler=md5_key_mangler
).configure(
'dogpile.cache.memory_pickle',
)
Session = scoped_session(
sessionmaker(
bind=e,
query_cls=query_callable(regions)
)
)
sess = Session()
sess.add(Config(person_ref=SomethingElse(age='45', name='se1')))
sess.add(Config(person_ref=Man(age='30', name='man1')))
sess.commit()
all_types = with_polymorphic(Person, "*", aliased=True)
conf = sess.query(Config).options(joinedload(Config.person_ref.of_type(all_types)), FromCache("default")).first()
sess.commit()
sess.close()
print "_____NO MORE SQL!___________"
conf = sess.query(Config).options(joinedload(Config.person_ref.of_type(all_types)), FromCache("default")).first()
print conf.person_ref.age
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3210 次 |
| 最近记录: |