1

継承と関係を持つ 3 つのモデルがあり、このモデルにクエリをキャッシュしたいと考えています。

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)

パーソナルから受け継いだモデルは他にもたくさんあります。たとえば、構成関係を介してMan属性にアクセスする必要があります。通常、私は次のようにします:

config = session.query(Config).join(Config.person_ref).filter(Person.type == 'man').first()
print config.person_ref.age

このようなクエリを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)

しかし、タイプをフィルタリングするにはjoinedloadが必要です。

4

1 に答える 1

5

「man」テーブルが確実にロードされるようにするために、of_type() をサブタイプの任意のパターンに使用できます。代わりに with_polymorphic() を使用して、完全なポリモーフィックな選択可能に参加できます。詳細については、 http://docs.sqlalchemy.org/en/latest/orm/inheritance.html#creating-joins-to-specific-subtypesの例を参照してください。必要なデータが 1 つの 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
于 2014-04-21T17:57:17.900 に答える