Как запомнить результаты запроса отношений SQLAlchemy (для реализации кэширования)? - PullRequest
2 голосов
/ 28 февраля 2010

Предположим, у меня есть сопоставленный класс Article. У него есть отношение category, которое выполняет запрос каждый раз, когда я к нему обращаюсь (article.category выдаст запрос для получения category или article).

Как мне прокси-вызов article.category, чтобы результат запрашивался из базы данных, затем запоминался и затем возвращался?

Спасибо, Бода Цидо.

Ответы [ 2 ]

3 голосов
/ 28 февраля 2010

Действительно ли SA выдает запрос каждый раз, когда вы получаете доступ к отношению в том же сеансе ? ИМО, это не должно происходить, поскольку результат должен автоматически кэшироваться в течение сеанса .

Чтобы убедиться, что SQL не выдается, просто включите ведение журнала и убедитесь сами:

metadata.bind.echo = 'debug'
c = session.query(Child).first() # issues SELECT on your child table(s)
print "child: ", c
print "c.parent: ", c.parent # issues SELECT on your parent table, then prints
print "c.parent: ", c.parent # just prints (no SQL)
print "c.parent: ", c.parent # just prints (no SQL)

Если ваш код работает по умолчанию, предоставьте фрагмент кода.

0 голосов
/ 28 февраля 2010

Если вам действительно нужно кэшировать результат, см. Ниже (решение, очень похожее на другой вопрос, который вы разместили):

class MyChild(Base):
    __tablename__ = 'MyChild'
    id = Column(Integer, primary_key=True)
    parent = relation('Parent')
    # ... other mapped properties

    def __init__(self):
        _parent_cached = None

    @property
    def parent_cached(self):
        if self._parent_cached is None:
            self._parent_cached = self.parent

Но чтобы получить результат, когда ваш объект отсоединен от сеанса, вы должны вызвать это свойство перед отсоединением. (Также не обрабатывается ситуация, когда parent равен None. У вас всегда есть родитель?).

Опция с активной загрузкой проще, и как только вы загрузите объект, у вас уже должно быть загружено отношение (ключ должен иметь lazy=False):

class MyChild(Base):
    __tablename__ = 'MyChild'
    id = Column(Integer, primary_key=True)
    parent = relation('Parent', lazy=False)
    # ... other mapped properties
    ...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...