如何避免DatabaseSessionsOver被外部调用

2024-05-08 16:47:27 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一些模型的定义,其中我重写了它们的__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__方法,或者修改包中的方法?。你知道吗

谢谢你

我一直在读prefetch method,但似乎不太合适。我不确定。你知道吗


Tags: 方法nameself实体iddbsearchreturn
1条回答
网友
1楼 · 发布于 2024-05-08 16:47:27

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

避免此异常的一种方法是在离开db_session之前加载所有必需的对象。在这种情况下,这些对象将位于标识映射中,不需要向数据库请求。你知道吗

另一种方法是用更大的作用域db_session包装所有代码,因此当您访问未从数据库加载的属性时,Pony可以在db_session内完成此操作。你知道吗

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

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

如果不清除缓存,则从数据库加载的所有对象都将位于内存中,直到您手动清除缓存或程序结束。你知道吗

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

相关问题 更多 >