1

我有一些模型定义,我已经覆盖了他们的__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)

DatabaseSessionIsOver在我使用Flask-PonyWhoosh 的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__方法或修改包中的方法?

谢谢,

PD:我一直在阅读预取方法,但似乎不合适。我不确定。

4

1 回答 1

2

发生异常DatabaseSessionIsOver是因为在您的repr方法中您试图访问关系属性,该属性不是从数据库加载的(self.a它试图返回实体的name属性)。A

避免此异常的一种方法是在您离开db_session. 在这种情况下,这些对象将位于身份映射中,并且不需要对数据库的请求。

另一种方法是将所有代码包装在更大的范围内db_session,这样当您访问未从数据库加载的属性时,Pony 可以在db_session.

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

  1. 清除身份映射缓存
  2. 将数据库连接返回到连接池

如果我们不清除缓存,那么从数据库加载的所有对象都将保留在内存中,直到您手动清除缓存或程序结束。

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

于 2015-11-26T09:57:47.243 回答