在Google App Engine中,如何配置bulkloader.yaml以处理模型中的可选外键?

2 投票
2 回答
1182 浏览
提问于 2025-04-17 10:53

我在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 个回答

0

处理这个问题的一种方法是:

  1. 使用一个叫做bulkloader.yaml的文件,导入所有没有键的实体,这个文件里不需要为模型指定键属性的导入转换。

  2. 导出所有的实体。

  3. 再导入这些实体。(现在它们都会有键值了)

还有一种稍微更好的方法:

  1. 使用一个带有键属性导入转换的bulkloader.yaml文件,导入所有有键的实体。

  2. 然后使用一个不带键属性导入转换的bulkloader.yaml文件,导入所有没有键的实体。

不过这样做有点麻烦。我希望能有一种方法,让在导入时自动给缺少键值的实体分配一个键值。

2

当你使用的 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=='']"

希望这对你有帮助。

撰写回答