App Engine:Google App Engine中的ReferencePropertyResolveError?

时间:2011-11-29 06:46:11

标签: python google-app-engine google-cloud-datastore

请帮助我理解为什么App Engine上出现此错误(Python 2.5,高复制)?

Traceback (most recent call last):
File "/base/python_runtime/python_lib/versions/1/google/appengine/ext/webapp/_webapp25.py", line 703, in __call__ 
    handler.post(*groups)
File "/base/data/home/apps/s~apptest/1.354937136776013205/main.py", line 963, in post
    get_purchases_for_user(pur.user, pur.car.model)
File "/base/python_runtime/python_lib/versions/1/google/appengine/ext/db/__init__.py", line 3592, in __get__
    reference_id.to_path())
ReferencePropertyResolveError: ReferenceProperty failed to be resolved: [u'User', 374836L]

背景:该应用程序是关于购买汽车的建议。

发生这种情况:大约每100笔交易大约2次,所以我真的不知道什么时候也不知道为什么。

代码中的对象 pur 定义为:

allPurchases = models.Purchase.all()
for pur in allPurchases:
   car = get_purchases_for_user(pur.user, pur.car.model)

我之前也把这个代码放了,我得到了同样的错误,当然引用了这一行

logging.error("Object user: %s, Car Model %s" % {str(pur.user), pur.car.model})

所以,问题不在于get_purchases_for_user函数

这些是数据存储区中的模型:

class User(db.Model):
    username = db.StringProperty(
        required=True)
    name = db.StringProperty(
        required=True)
    email = db.EmailProperty(
        required=True)
    password = db.StringProperty(
        required=True)

class Car(db.Model):
    model = db.StringProperty()
    name = db.StringProperty()
    year = db.DateTimeProperty()

class Purchase(db.Model):
    user = db.ReferenceProperty(User,
        collection_name='recommendations')
    car = db.ReferenceProperty(Car,
        collection_name='recommendations')
    when = db.DateTimeProperty(
        auto_now=True)

2 个答案:

答案 0 :(得分:3)

您的实体有ReferencePropertyUser实体不存在 - 很可能是因为它已被删除。您可以添加代码来捕获此特定异常,并以适合您应用程序的任何方式处理它。

答案 1 :(得分:2)

我倾向于问题是数据存储的高复制和缺乏保证的一致性。来自谷歌文档:

  

但是,在High Replication数据存储区中,跨实体组的查询(换句话说,非祖先查询)可能会返回过时的结果。为了在High Replication环境中返回强一致的查询结果,您需要查询单个实体组。这种类型的查询称为祖先查询。

     

祖先查询起作用,因为实体组是一致性单位:所有操作都应用于整个组。在整个实体组是最新的之前,祖先查询不会返回数据。因此,从实体组上的祖先查询返回的数据非常一致。

     

如果您的应用程序依赖于某些查询的高度一致的结果,则可能必须更改应用程序存储实体的方式。本页讨论了使用存储在High Replication数据存储区中的数据的最佳实践。让我们分别使用示例留言簿应用程序来查看主/从和高复制数据存储的工作原理。

如此有效,您可能正在查询刚写入的内容,但未在整个数据存储区中传播。因此,当您引用该属性时,就好像它从未存在或被删除一样。

看起来您正在使用.all()来检索数据。如果可能的话,我建议重新编写它以使用GQL和祖先查询。或者可能及时限制数据以允许传播。有关祖先查询的文档:http://code.google.com/appengine/docs/python/datastore/queries.html#Ancestor_Queries