【问题标题】:Overriding db.Model.all() in python google app engine在 python 谷歌应用引擎中覆盖 db.Model.all()
【发布时间】:2012-09-18 01:25:38
【问题描述】:

我正在尝试在我的 Google App Engine 应用中开始使用内存缓存。我没有创建一个检查内存缓存然后可能查询数据库的函数,而是决定重写我的模型的 all() 类方法。到目前为止,这是我的代码:

def all(cls, order=None):
    result = memcache.get("allitems")
    if not result or not memcache.get("updateitems"):
        logging.info(list(super(Item, cls.all())))
        result = list(super(Item, cls).all()).sort(key=lambda x: getattr(x, order) if order else str(x))
        memcache.set("allitems", result)
        memcache.set("updateitems", True)
        logging.info("DB Query for items")
    return result

我认为这会奏效。但相反,我得到一个 RuntimeError 说超出了递归深度。我认为这来自对 super() 方法的误解。很抱歉把代码和订购的东西弄乱了。但也许问题也出在某个地方。我发现一个地方说超级方法应该这样调用:

super(supercls, cls_or_self)

但这不适用于 GAE 的 API:

super(db.Model, cls)

这不知道要查询哪个模型。有人请告诉我我做错了什么,也许让我更好地理解 super()。

编辑:感谢@Matthew,问题出在第一个 logging.info() 调用中的括号放错了位置。现在我有另一个问题,该方法只是返回无。我不知道这是否意味着 all()super 实现返回 None (也许它不知道是什么实体在调用它?)或者只是我的代码存在其他错误。

【问题讨论】:

标签: python google-app-engine superclass overriding


【解决方案1】:

我认为错误可能在这里:

logging.info(list(super(Item, cls.all())))

如果cls.all() 中有错误,那么您再次将其作为super 构造函数的一部分调用,而不是在结果上调用它:

logging.info(list(super(Item, cls).all()))

因此,如果错误再次调用all,它仍然会满足日志记录分支条件,这将再次调用all,这仍然会等等,直到你达到递归限制。

另一个可能的问题是Model.all() 返回一个Query 对象,我不确定list(query) 是否有效。它还提供了自己的排序,因此您可以使用它来代替:

    query = super(Item, cls).all()
    query.order( order )
    ...
return list(query)

或者只是return query,因为它已经可以迭代了。

【讨论】:

  • 谢谢!我评论了那条线,它起作用了!......有点。现在该方法返回“无”。有什么想法吗?
  • logging.info 行是否提供了一个列表,或者它是否也返回了None
  • 它显示一个空列表。我知道它 None 的原因是因为调用它的函数说“Nonetype 不可迭代”,因为我试图迭代查询的结果。我可能错了,但我认为您可以合法地“迭代”一个空列表。
  • 自从我使用 GAE 已经 3 年了,所以很遗憾,我们已经达到了我的知识极限,但问题可能只是当它返回一个 @ 时,你期待一个列表987654335@ 对象。我已经更新了答案。
  • 我最初使用了这种方法,但后来我意识到(或怀疑)查询对象实际上并没有从数据库中读取,直到您尝试迭代它或访问一个元素。这当然会破坏缓存查询的目的。我还在学习 GAE,所以我可能错了。
猜你喜欢
  • 2018-09-04
  • 2011-01-11
  • 2014-07-20
  • 2011-08-21
  • 2011-03-05
  • 2016-08-01
  • 2011-05-06
  • 1970-01-01
相关资源
最近更新 更多