重写python google应用程序引擎中的db.Model.all()
我正在尝试在我的Google应用程序引擎应用程序中使用memcache。我决定只重写模型的all()类方法,而不是创建一个检查memcache然后查询数据库的函数。以下是我目前的代码:重写python google应用程序引擎中的db.Model.all(),python,google-app-engine,superclass,overriding,Python,Google App Engine,Superclass,Overriding,我正在尝试在我的Google应用程序引擎应用程序中使用memcache。我决定只重写模型的all()类方法,而不是创建一个检查memcache然后查询数据库的函数。以下是我目前的代码: def all(cls, order=None): result = memcache.get("allitems") if not result or not memcache.get("updateitems"): logging.info(list(super(Item, c
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
我原以为这样行得通。但是相反,我得到了一个运行时错误,说已经超过了递归深度。我认为这是由于对super()方法的误解。很抱歉,订购时把代码弄乱了。但问题也可能出在那里的某个地方。我发现的一个地方说超级方法应该这样调用:
super(supercls, cls_or_self)
但这不适用于GAE的API:
super(db.Model, cls)
这不知道要查询哪个模型。有人请告诉我我做错了什么,也许能让我更好地理解super()
编辑:多亏了@Matthew,问题变成了第一个
logging.info()
调用中的括号放错了位置。现在我有另一个问题,这个方法只是返回None。我不知道这是否意味着all()
的super
实现没有返回任何值(可能它不知道哪个实体在调用它?),或者只是我的代码中存在一些其他错误。我想错误可能在这里:
logging.info(list(super(Item, cls.all())))
如果cls.all()
中有错误,则作为super
构造函数的一部分再次调用它,而不是在结果中调用它:
logging.info(list(super(Item, cls).all()))
因此,如果一个错误将再次调用all
,它仍将满足日志记录分支条件,这将再次调用all
,直到达到递归限制为止
另一个可能的问题是Model.all()
返回一个对象,我不确定list(query)
是否有效。它还提供了自己的排序,因此您可以使用它:
query = super(Item, cls).all()
query.order( order )
...
return list(query)
或者只是
返回查询
,因为它已经可以使用了。也可以考虑切换到NDB,在那里您可以进行开箱即用的自动缓存。。非常酷:谢谢!我评论了这句话,它成功了!。。。某种程度上。现在,该方法返回“None”。有什么想法吗?logging.info
行是否提供了一个列表,或者它是否也返回了None
?它显示了一个空列表。我之所以知道它是None,是因为调用它的函数说“Nonetype是不可iterable的”,因为我试图迭代查询的结果。我可能错了,但我认为你可以合法地“迭代”一个空列表。自从我使用GAE以来已经整整三年了,所以我们已经达到了我的知识极限,不幸的是,问题可能只是当它返回一个查询
对象时,你期望的是一个列表。我已经更新了答案。我最初使用了这种方法,但后来我意识到(或怀疑)在您尝试迭代数据库或访问元素之前,查询对象实际上不会从数据库中读取数据。当然,这会破坏缓存查询的目的。我还在学GAE,所以我可能错了。