Python 应用引擎:谷歌应用引擎中的ReferencePropertyResolveError?

Python 应用引擎:谷歌应用引擎中的ReferencePropertyResolveError?,python,google-app-engine,google-cloud-datastore,Python,Google App Engine,Google Cloud Datastore,请帮助我理解为什么在应用程序引擎(Python 2.5,高复制)上出现此错误 我把这段代码放在前面,得到了同样的错误,当然是引用这行代码 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

请帮助我理解为什么在应用程序引擎(Python 2.5,高复制)上出现此错误

我把这段代码放在前面,得到了同样的错误,当然是引用这行代码

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)

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

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

祖先查询之所以有效,是因为实体组是一个一致性单元:所有操作都应用于整个组。在整个实体组更新之前,祖先查询不会返回数据。因此,从实体组的祖先查询返回的数据具有很强的一致性

如果应用程序依赖于某些查询的强一致性结果,则可能必须更改应用程序存储实体的方式。本页讨论使用高复制数据存储中存储的数据的最佳做法。让我们分别使用主/从和高复制数据存储的示例留言簿应用程序来了解这一点

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


看起来您正在使用.all()检索数据。如果可能的话,我建议重新编写它以使用GQL和祖先查询。或者限制数据的时间以允许传播。关于祖先查询的文档:

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

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

祖先查询之所以有效,是因为实体组是一个一致性单元:所有操作都应用于整个组。在整个实体组更新之前,祖先查询不会返回数据。因此,从实体组的祖先查询返回的数据具有很强的一致性

如果应用程序依赖于某些查询的强一致性结果,则可能必须更改应用程序存储实体的方式。本页讨论使用高复制数据存储中存储的数据的最佳做法。让我们分别使用主/从和高复制数据存储的示例留言簿应用程序来了解这一点

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



看起来您正在使用.all()检索数据。如果可能的话,我建议重新编写它以使用GQL和祖先查询。或者限制数据的时间以允许传播。关于祖先查询的文档:

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

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

您是否确认您确实有一个ID为
374836
User
实体?不,我没有。但是应用程序如何调用一个从未存在过的实体呢?我猜想,它是在创建ReferenceProperty时存在的,然后在没有考虑引用完整性的情况下被删除的。除非您做了一些疯狂的事情,比如以编程方式在ReferenceProperty中创建键,而不将其指向实际实体。不可能。应用程序从不删除用户。我完全肯定,那么,你确认用户存在吗?只需2分钟,对可能出错的事情的假设数量将减半。您是否确认您确实拥有ID为374836的
User
实体?不,我没有。但是应用程序如何调用一个从未存在过的实体呢?我猜想,它是在创建ReferenceProperty时存在的,然后在没有考虑引用完整性的情况下被删除的。除非您做了一些疯狂的事情,比如以编程方式在ReferenceProperty中创建键,而不将其指向实际实体。不可能。应用程序从不删除用户。我完全肯定,那么,你确认用户存在吗?只需2分钟,对可能出错的事情的假设数量将减半。不真实-数据存储get操作将始终返回实体(如果存在)。Nick,请详细说明-我是否误解了,或者引用的文档是否不正确?ReferenceProperty执行数据存储获取操作以检索引用的实体。数据存储总是返回一个实体,如果它存在-最终的一致性不适用。谢谢!如果你能有人把这个用例也包括在文档中,那就太好了。我不确定我是否理解-你想包括什么
logging.error("Object user: %s, Car Model %s" % {str(pur.user), pur.car.model})
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)