使用重复的整数属性获取Python NDB时出错 [英] Error when fetch Python NDB with repeated integer property

查看:48
本文介绍了使用重复的整数属性获取Python NDB时出错的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个应用引擎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:

  1. 如果仅在devappserver中运行,请通过运行 devappserver.py --clear_datastore
  2. 清除数据存储
  3. 搜索所有值为None的对象,并将其替换为空列表.这可能看起来像这样:

  1. If you are only running in the devappserver, clear your datastore by running devappserver.py --clear_datastore
  2. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆