GAE端点错误:预期的FooBar实例,得到了FooBar()

时间:2014-07-21 16:21:50

标签: google-app-engine google-cloud-datastore google-cloud-endpoints app-engine-ndb

我正在使用Google Cloud Endpoints管理API,并且正在努力应对一个奇怪的,随机发生的错误。该错误仅在生产中发生,单元测试通过属性。

我有以下型号:

class UserFacebookData(ndb.Model):
  facebook_id = ndb.StringProperty(required=True, indexed=True)
  facebook_token = ndb.StringProperty(required=True, indexed=True)

class User(ndb.Model, Entity): 
  created = ndb.DateTimeProperty(auto_now_add=True, indexed=True)
  username = ndb.StringProperty(indexed=True)
  facebook_data = ndb.StructuredProperty(UserFacebookData, indexed=False)

使用它来创建用户

ufd = UserFacebookData(facebook_id=some_api_data, facebook_token=some_api_data)
user = User(username=some_api_data, facebook_data=ufd)
user.save()

或更新一个

ufd = UserFacebookData(facebook_id=some_api_data, facebook_token=some_api_data)    
user = get_from_db(some_api_data)
user.facebook_data = ufd
user.save()

(编辑:save()是父实体类的一个方法,执行put()+一些memcached的东西)

不时更新用户时出现以下错误

Expected UserFacebookData instance, 
got UserFacebookData(facebook_id=u'xxx', facebook_token=xxx'))

然而,痕迹(打印和检查ufd / UserFacebookData实例的类型)显示它已正确创建并且用户也存在

# print user.username
my_username
# print UserFacebookData
UserFacebookData(facebook_id=u'xx', facebook_token=xx')
# print type(UserFacebookData)
UserFacebookData<facebook_id=StringProperty('facebook_id', required=True), 
facebook_token=StringProperty('facebook_token', required=True)>

我看不出我错过了什么。有人已经体验过 - 并希望修复它吗?这是完整的错误堆栈

Encountered unexpected error from ProtoRPC method implementation: BadValueError (Expected UserFacebookData instance, got UserFacebookData(facebook_id=u'xx', facebook_token=xx'))
Traceback (most recent call last):
  File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/protorpc-1.0/protorpc/wsgi/service.py", line 181, in protorpc_service_app
response = method(instance, request)
  File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/endpoints-1.0/endpoints/api_config.py", line 1329, in invoke_remote
return remote_method(service_instance, request)
  File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/protorpc-1.0/protorpc/remote.py", line 412, in invoke_remote_method
response = method(service_instance, request)
  File "/base/data/home/apps/s~yapme-web/alpha2.377359917212322950/api/helpers.py", line 43, in method
return func(*args, **kwargs)
  File "/base/data/home/apps/s~xx-web/alpha2.377359917212322950/api/user.py", line 25, in users_create
user = User.create(request)
  File "/base/data/home/apps/s~xx-web/alpha2.377359917212322950/entities/users.py", line 168, in create
user.facebook_data = facebook_data
  File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/ext/ndb/model.py", line 1339, in __set__
    self._set_value(entity, value)
  File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/ext/ndb/model.py", line 1084, in _set_value
value = self._do_validate(value)
  File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/ext/ndb/model.py", line 1031, in _do_validate
value = self._call_shallow_validation(value)
  File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/ext/ndb/model.py", line 1223, in _call_shallow_validation
return call(value)
  File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/ext/ndb/model.py", line 1270, in call
newvalue = method(self, value)
  File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/ext/ndb/model.py", line 2269, in _validate
(self._modelclass.__name__, value))
BadValueError: Expected UserFacebookData instance, got UserFacebookData(facebook_id=u'xx', facebook_token=xx')

2 个答案:

答案 0 :(得分:0)

save()不是ndb语法。我想你想put()。此外,您应该只能使用dict来设置StructuredProperty值:

创建用户:

ufd = {"facebook_id":some_api_data, "facebook_token":some_api_data}
user = User(username=some_api_data, facebook_data=ufd)
user.put()

更新用户:

ufd = {"facebook_id":some_api_data, "facebook_token":some_api_data}   
user = get_from_db(some_api_data)
user.facebook_data = ufd
user.put()

这应该允许您同时保存两者。否则,您最终可能会遇到最终一致性问题。这很可能就是问题所在,正如你所说,这只是间歇性地发生在生产中。

答案 1 :(得分:0)

我遇到了同样的问题,并在此处发布了答案:App Engine BadValueError when saving ndb LocalStructured entity。基本上问题是由相对导入引起的,所以python认为FooBar在不同的包中。