使用重复的整数属性获取Python NDB时出错 [英] Error when fetch Python NDB with repeated integer property
问题描述
我有一个应用引擎Python NDB模型,如下所示:
I have an app engine Python NDB Model that looks like this:
class Car(ndb.Model)
name=ndb.StringProperty()
tags=ndb.IntegerProperty(repeated=True)
我要使用钥匙取车时使用:
when I go to fetch a Car by key I use:
car = ndb.Key('Car', long(6079586488025088)).get()
当我这样做时,我会看到:
when I do this I am seeing:
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/ext/ndb/key.py", line 532, in get
return self.get_async(**ctx_options).get_result()
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/ext/ndb/tasklets.py", line 325, in get_result
self.check_success()
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/ext/ndb/tasklets.py", line 371, in _help_tasklet_along
value = gen.send(val)
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/ext/ndb/context.py", line 689, in get
pbs = entity._to_pb(set_key=False).SerializePartialToString()
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/ext/ndb/model.py", line 3052, in _to_pb
prop._serialize(self, pb, projection=self._projection)
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/ext/ndb/model.py", line 1365, in _serialize
values = self._get_base_value_unwrapped_as_list(entity)
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/ext/ndb/model.py", line 1135, in _get_base_value_unwrapped_as_list
wrapped = self._get_base_value(entity)
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/ext/ndb/model.py", line 1123, in _get_base_value
return self._apply_to_values(entity, self._opt_call_to_base_type)
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/ext/ndb/model.py", line 1295, in _apply_to_values
value[:] = map(function, value)
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/ext/ndb/model.py", line 1177, in _opt_call_to_base_type
value = _BaseValue(self._call_to_base_type(value))
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/ext/ndb/model.py", line 1198, in _call_to_base_type
return call(value)
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/ext/ndb/model.py", line 1274, in call
newvalue = method(self, value)
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/ext/ndb/model.py", line 1536, in _validate
(value,))
BadValueError: Expected integer, got None
如果我从模型定义中删除该属性,它将返回正常,因此我知道它是此属性.在数据存储区中,该字段被列为具有空值.知道为什么会这样以及如何处理吗?谢谢!
if I remove that property from the model definition it returns fine, so I know it's this property. In the datastore it is listed as having a null value for that field. Any idea why this is happening and how to deal with it? Thanks!
推荐答案
通常,当您首先拥有一个非重复的单个属性,然后将其转换为重复的属性时,通常会发生这种情况.最初执行 put()
时,如果尚未设置属性,它将用None填充值.但是,如果您随后将其变成重复的属性,则ndb会读取此内容并认为您想要 [None]
.由于 None
不是有效的IntegerProperty,因此尝试序列化和 put()
数据将失败.
This generally occurs when you first have a single, non-repeated property and then convert it to a repeated property. When you initially do a put()
, if you have not yet set the property it will fill the value with None. However, if you then turn it into a repeated property, ndb will read this and think you want [None]
. Because None
is not a valid IntegerProperty, trying to serialize and put()
the data will fail.
在您的示例中,它在 get()
上失败,因为从数据存储区执行 get()
后,它尝试序列化数据并将其放入内存缓存.
In your example it fails on a get()
because after doing a get()
from the datastore it tries to serialize the data and put it in memcache.
根据您的情况,您有两种选择:
Depending on your situation, you have a couple of options:
- 如果仅在devappserver中运行,请通过运行
devappserver.py --clear_datastore
清除数据存储 -
搜索所有值为None的对象,并将其替换为空列表.这可能看起来像这样:
- If you are only running in the devappserver, clear your datastore by running
devappserver.py --clear_datastore
Do a search for all objects with a None value and replace them with the empty list. This might look something like this:
for c in Car.query(Car.tags=None):
c.tags=[]
c.put()
请注意,您在这里需要注意一些事项.首先,以防万一,请确保c.tags仅是[None],不是[a,b,c,None].其次,如果您有很多没有标签的汽车,那么您将无法在同一请求中处理所有这些汽车.您要么要在后端上运行,要么将数据传递给Tasks进行处理.
Note that you have to be careful about a few things here. First, make sure that c.tags only is [None] and not [a, b, c, None], just in case. Second, if you have a lot of Cars with no tags, you won't be able to handle fixing them all in the same request. You'll either want to run on a backend, or pass the data on to Tasks for processing.
这与#2非常相似,但是如果您的数据很少,则可以使用数据存储查看器,并简单地使用标签= None重新保存实体.
This is pretty similar to #2, but if you have very little data you could use the Datastore viewer and simply resave the entities with tags = None.
这篇关于使用重复的整数属性获取Python NDB时出错的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!