如何避免来自外部调用的DatabaseSessionIsOver

时间:2015-09-04 05:40:29

标签: python ponyorm

我有一些模型的定义,我已经覆盖了他们的__repr__方法。例如,让我们考虑以下实体:

def A(db.Entity):
    id = PrimaryKey(int, auto=True)
    name = Required(unicode)
    b = Optional("B")

    def __repr__(self):
       return self.name

def B(db.Entity):
    id = PrimaryKey(int, auto=True)
    name = Required(unicode)
    a = Required("A")

    def __repr__(self):
        return '{n} from a={aname}'.format(n=self.name, aname = self.a)

Flask-PonyWhoosh使用DatabaseSessionIsOver方法,即使使用search(B, 'aaaa封装在db_session内,也会引发@orm.db_session def search(model, *arg, **kw): return model._wh_.search(*arg, **kw) 异常:

__repr__

只有在某个实体以我在上面的示例中所做的方式覆盖with db_session: print(search(A, 'karl')) 方法时才会引发异常。

然而,我用以避免以下句子的问题:

with ...

所以,很快,问题是,有没有办法避免使用__repr__,可能修改<div th:if="${ #authorization.expression('isAuthenticated()') and #strings.contains(#authentication.principal.authorities,'ADMIN')}"> <a th:href="@{/somelink}">ADMIN LINK</a> </div> 方法或修改包中的方法?

谢谢,

PD :我一直在阅读prefetch method但似乎不合适。我不确定。

1 个答案:

答案 0 :(得分:1)

发生例外DatabaseSessionIsOver,因为在您的repr方法中,您尝试访问未从数据库加载的关系属性(self.a尝试返回name实体的A属性。

避免此异常的一种方法是在离开db_session之前加载所有必需的对象。在这种情况下,这些对象将位于Identity Map中,并且不需要对数据库的请求。

另一种方法是使用更大的范围db_session包装所有代码,因此当您访问未从数据库加载的属性时,Pony可以在db_session中执行此操作。

Pony需要使用@db_session,因为它设置了数据库对话的边界并允许释放资源:

  1. 清除身份地图缓存
  2. 将数据库连接返回到连接池
  3. 如果我们不清除缓存,那么从数据库加载的所有对象都将驻留在内存中,直到您手动清除缓存或程序结束。

    我们假设我们在db_session永不结束时引入模式,您需要手动清除缓存。你认为它会解决你的问题并且你会使用它吗?