Google app engine GAE:下载数据时出错,如果ndb.KeyProperty(repeated=True)
我正在从现有架构自动创建bulkloader.yaml,由于KeyProperty的Google app engine GAE:下载数据时出错,如果ndb.KeyProperty(repeated=True),google-app-engine,app-engine-ndb,Google App Engine,App Engine Ndb,我正在从现有架构自动创建bulkloader.yaml,由于KeyProperty的repeated=True,下载数据时遇到问题 class User(ndb.Model): firstname = ndb.StringProperty() friends = ndb.KeyProperty(kind='User', repeated=True) 自动创建的bulkloader如下所示: - kind: User connector: csv connector_o
repeated=True
,下载数据时遇到问题
class User(ndb.Model):
firstname = ndb.StringProperty()
friends = ndb.KeyProperty(kind='User', repeated=True)
自动创建的bulkloader如下所示:
- kind: User
connector: csv
connector_options:
# TODO: Add connector options here--these are specific to each connector.
property_map:
- property: __key__
external_name: key
export_transform: transform.key_id_or_name_as_string
- property: firstname
external_name: firstname
# Type: String Stats: 2 properties of this type in this kind.
- property: friends
external_name: friends
# Type: Key Stats: 2 properties of this type in this kind.
import_transform: transform.create_foreign_key('User')
export_transform: transform.key_id_or_name_as_string
[datastore_types.Key.from_path(u'User', u'kave@gmail.com', _app=u's~myapp1')]
这是我收到的错误消息:
google.appengine.ext.bulkload.bulkloader_errors.ErrorOnTransform: Error on transform. Property: friends External Name: friends. Code: transform.key_id_or_name_as_string Details: 'list' object has no attribute 'to_path'
请问我能做什么
可能的解决方案:
在Tony给我小费后,我想到了这个:
- property: friends
external_name: friends
# Type: Key Stats: 2 properties of this type in this kind.
import_transform: myfriends.stringToValue(';')
export_transform: myfriends.valueToString(';')
myfriends.py
def valueToString(delimiter):
def key_list_to_string(value):
keyStringList = []
if value == '' or value is None or value == []:
return None
for val in value:
keyStringList.append(transform.key_id_or_name_as_string(val))
return delimiter.join(keyStringList)
return key_list_to_string
这很有效!但是编码是Unicode的:UTF-8。确保在LibreOffice中打开文件,否则会看到乱码内容
最大的挑战是进口。这就是我在没有任何运气的情况下想到的:
def stringToValue(delimiter):
def string_to_key_list(value):
keyvalueList = []
if value == '' or value is None or value == []:
return None
for val in value.split(';'):
keyvalueList.append(transform.create_foreign_key('User'))
return keyvalueList
return string_to_key_list
我收到错误消息:
BadValueError: Unsupported type for property friends: <type 'function'>
更新2:
托尼,你将成为散货船方面的真正专家。谢谢你的帮助。你的解决方案奏效了!
我把我的另一个问题转移到一个新的话题上
但出现的一个关键问题是,当我创建新用户时,我可以看到我的朋友字段显示为
,并且工作正常
现在,当我使用您的解决方案上载数据时,对于那些没有任何好友条目的用户,我看到了一个
条目。不幸的是,这似乎打破了模型,因为friends不能为null
改变模型以反映这一点似乎被忽略了
friends = ndb.KeyProperty(kind='User', repeated=True, required=False)
请问我该怎么修
更新:
进一步挖掘:
当状态
显示在data viewer中时,在代码中会显示friends=[]
然而,当我通过csv上传数据时,我得到了一个
,它转换为朋友=[None]
。我知道这一点,因为我将数据导出到本地数据存储中,并可以在代码中跟踪它。奇怪的是,如果我清空列表del user.friends[:]
,它会正常工作。必须有一个更好的方式来设置它,而上传通过csv虽然
最终解决方案
这是一个一年多以来一直没有解决的问题
简而言之,即使csv中没有值,因为需要一个列表,gae也会生成一个包含None的列表。这是一个突破性的游戏,因为这样一个模型的检索以瞬间崩溃告终
添加一个post\u import\u函数
,该函数将删除包含None的列表
就我而言:
def post_import(input_dict, instance, bulkload_state_copy):
if instance["friends"] is None:
del instance["friends"]
return instance
最后,一切正常。当您使用重复属性并导出到CSV时,您应该进行一些格式化,以将列表连接到CSV可理解的格式。请检查下面的示例,希望它能帮助您
编辑:添加从先前注释到此答案的导入转换建议
要导入,请尝试以下操作:
`from google.appengine.api import datastore
def stringToValue(delimiter):
def string_to_key_list(value):
keyvalueList = []
if value == '' or value is None or value == []: return None
for val in value.split(';'):
keyvalueList.append(datastore.Key.from_path('User', val))
return keyvalueList
return string_to_key_list`
如果您使用的是id而不是名称,请添加类似val=int(val)当您使用重复属性并导出到CSV时,您应该进行一些格式化,以将列表连接到CSV可理解的格式。请检查下面的示例,希望它能帮助您
编辑:添加从先前注释到此答案的导入转换建议
要导入,请尝试以下操作:
`from google.appengine.api import datastore
def stringToValue(delimiter):
def string_to_key_list(value):
keyvalueList = []
if value == '' or value is None or value == []: return None
for val in value.split(';'):
keyvalueList.append(datastore.Key.from_path('User', val))
return keyvalueList
return string_to_key_list`
如果您有id而不是姓名,请添加类似val=int(val)Tony,非常感谢您的帮助。我已经成功地完成了导出,并且成功了。但就我而言,进口是非常困难的。你知道我怎么做吗?请参阅更新的问题。对于导入,请尝试以下操作:from google.appengine.api导入数据存储def stringToValue(分隔符):def string_to_key_list(value):keyvalueList=[]如果value=''或value为None或value=[]:为value中的val返回None。拆分(“;”):keyvalueList.append(datastore.Key.from_path('User',val))return keyvalueList return string_to_Key_list
如果您有id而不是名称,请添加like val=int(val)Tony,如果您将导入建议放在主要答案中,则可以正确格式化它。:-)@GuidovanRossum,我已经将代码建议移到我的答案中,以获得正确的格式。请您看看代码逻辑是否正确。@tony,非常感谢您在这方面的帮助。是的,它似乎起了作用。但有一个相关的问题,我已经在更新的问题中解释过。GAE分配了非常高的id,这在重新上传时成为一个问题。托尼,非常感谢你的帮助。我已经成功地完成了导出,并且成功了。但就我而言,进口是非常困难的。你知道我怎么做吗?请参阅更新的问题。对于导入,请尝试以下操作:from google.appengine.api导入数据存储def stringToValue(分隔符):def string_to_key_list(value):keyvalueList=[]如果value=''或value为None或value=[]:为value中的val返回None。拆分(“;”):keyvalueList.append(datastore.Key.from_path('User',val))return keyvalueList return string_to_Key_list
如果您有id而不是名称,请添加like val=int(val)Tony,如果您将导入建议放在主要答案中,则可以正确格式化它。:-)@GuidovanRossum,我已经将代码建议移到我的答案中,以获得正确的格式。请您看看代码逻辑是否正确。@tony,非常感谢您在这方面的帮助。是的,它似乎起了作用。但有一个相关的问题,我已经在更新的问题中解释过。GAE分配非常高的id,这在重新上传时成为一个问题。