在Google App Engine中,如何配置bulkloader.yaml以处理模型中的可选外键?
我在App Engine上有一个模型,我把它导出成CSV格式,然后用appcfg.py和bulkloader.yaml导入到我本地的开发环境中。
我可以导入和导出大部分模型,但对于那些有外键的模型,我遇到了一些问题,因为外键并不总是存在。我可以使用下面的lambda导入,始终将外键导入为None
,或者使用create_foreign_key()
转换,当我的CSV文件中的每一行都有外键时导入外键。
我该如何配置bulkloader.py,以便在外键存在时导入它,而在外键不存在时忽略它呢?
- kind: MyModel
connector: csv
connector_options:
property_map:
- property: myOtherModel
external_name: myOtherModel
import_transform: "lambda x: x is None and None or None"
#import_transform: transform.create_foreign_key('MyOtherModel', key_is_id=True)
export_transform: transform.key_id_or_name_as_string
仅仅把第二个import_transform
的注释去掉,替换掉lambda转换,会导致这个错误。
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/bulkload/transform.py", line 127, in generate_foreign_key_lambda
value = int(value)
ValueError: invalid literal for int() with base 10: ''
当我运行appcfg.py时会出现这个错误。其他没有外键或者外键总是存在的导入都正常工作。
appcfg.py upload_data --config_file=bulkloader.yaml --num_threads=1 --batch_size=50 --url=http://localhost:8080/remote_api --email=Chris --passin --kind=MyModel --filename=MyModel.csv
CSV文件中的myOtherModel
列有时包含MyOtherModel.key().id()
,有时则没有。
例如:
myOtherModel
1234
4567
2345
5678
2 个回答
处理这个问题的一种方法是:
使用一个叫做bulkloader.yaml的文件,导入所有没有键的实体,这个文件里不需要为模型指定键属性的导入转换。
导出所有的实体。
再导入这些实体。(现在它们都会有键值了)
还有一种稍微更好的方法:
使用一个带有键属性导入转换的bulkloader.yaml文件,导入所有有键的实体。
然后使用一个不带键属性导入转换的bulkloader.yaml文件,导入所有没有键的实体。
不过这样做有点麻烦。我希望能有一种方法,让在导入时自动给缺少键值的实体分配一个键值。
当你使用的 foreign key
值不存在时,reference property
的默认行为是会变成 None
,相关的代码如下:
import_transform: transform.create_foreign_key('MyOtherModel')
根据你的错误信息:value does not exist
,这说明你使用了 'othercolumn','','anohtercolumn'
,而应该使用 'othercolumn',,'anohtercolumn'
。
所以如果源是 '',你需要处理这个问题:
可以参考这个链接: http://eikke.com/python-ifelse-in-lambda/,正如 Thomas Thurman 评论的那样,lambda 表达式应该像这样:
import-transform: "lambda x: [x, None][x=='']"
希望这对你有帮助。