代码的相关部分:
pk = int(pk)
logging.info('pk: %r :: %s', pk, type(pk))
instance = models.Model.get_by_id(int(pk))
上面日志消息的输出
pk: 757347 :: <type 'int'>
stacktrace:
Traceback (most recent call last):
File "/base/python_runtime/python_lib/versions/1/google/appengine/ext/webapp/__init__.py", line 634, in __call__
handler.get(*groups)
File "/base/data/home/apps/<myapp>/<version>/scrape.py", line 61, in get
instance = models.Model.get_by_id(int(pk))
File "/base/python_runtime/python_lib/versions/1/google/appengine/ext/db/__init__.py", line 1212, in get_by_id
return get(keys[0], config=config)
File "/base/python_runtime/python_lib/versions/1/google/appengine/ext/db/__init__.py", line 1434, in get
model = cls1.from_entity(entity)
File "/base/python_runtime/python_lib/versions/1/google/appengine/ext/db/__init__.py", line 1350, in from_entity
instance = cls(None, _from_entity=True, **entity_values)
File "/base/python_runtime/python_lib/versions/1/google/appengine/ext/db/__init__.py", line 890, in __init__
prop.__set__(self, value)
File "/base/python_runtime/python_lib/versions/1/google/appengine/ext/db/__init__.py", line 593, in __set__
value = self.validate(value)
File "/base/python_runtime/python_lib/versions/1/google/appengine/ext/db/__init__.py", line 2967, in validate
% (self.name, type(value).__name__))
BadValueError: Property pk must be an int or long, not a unicode
任何人都知道我在这里做错了吗?
注意:从代码的最后一行删除int
没有区别(这是第一个版本)。
此外,代码在dev_appserver.py
上也没有问题。
答案 0 :(得分:5)
你的模型是否有一个属性'pk',它现在是一个IntegerProperty(),但以前是一个StringProperty(),而id为757347的实体是用旧版本的模型保存的?
答案 1 :(得分:2)
为您的pk IntegerProperty创建自定义验证器。
我认为@ saxon-druce对于失败的原因有正确的认识。
您正在从数据存储区接收实体,而from_entity函数正在将实体中的数据应用于db.Model的初始化程序。
验证来自google/appengine/ext/db/__init__.py
来自SDK
class IntegerProperty(Property):
"""An integer property."""
def validate(self, value):
"""Validate integer property.
Returns:
A valid value.
Raises:
BadValueError if value is not an integer or long instance.
"""
value = super(IntegerProperty, self).validate(value)
if value is None:
return value
if not isinstance(value, (int, long)) or isinstance(value, bool):
raise BadValueError('Property %s must be an int or long, not a %s'
% (self.name, type(value).__name__))
if value < -0x8000000000000000 or value > 0x7fffffffffffffff:
raise BadValueError('Property %s must fit in 64 bits' % self.name)
return value
data_type = int
创建自己的简单验证器,尝试将字符串解析为int。 最终,您可能希望在所有这些实体中应用映射器,以使它们完全符合当前架构。
在value = super(IntegerProperty, self).validate(value)
内调用验证器
所以该值应该可以在适当的时候用作int。
示例验证器
def str_int_validator(value):
if isinstance(value, basestring):
if value.isdigit():
return int(value)
else:
raise db.BadValueError("Property expected str or int got %r" % value)
else:
return value
class Foo(db.Model):
pk = db.IntegerProperty(validator=str_int_validator)
此代码尚未经过测试。
答案 2 :(得分:1)
删除一个实体/表格中的所有元素,然后尝试通过csv / bulkloader上传新值后,我收到了同样的错误消息。
解决方案是添加以下行
import_transform: transform.none_if_empty(int)
到批量加载器的yaml文件中的属性定义。