使用自动生成的YAML配置和带有数字ID的实体时,Google App Engine bulkloader问题

5 投票
2 回答
1706 浏览
提问于 2025-04-16 00:30

我的应用程序使用的是 Django non-rel。我没有访问模型的权限。

我有一个名为 bulkloader.yaml 的文件,它是通过 appcfg.py create_bulkloader_config 自动生成的。

问题是,实体的数字 ID 被导入为字符串键名。所以如果我导出一个整数 ID,比如说 '62',它会被导入为字符串键名 '61',这就搞砸了 Django。

相关的 bulkloader.yaml 片段:

 property_map:
  - property: __key__
    external_name: key
    export_transform: transform.key_id_or_name_as_string

我正在尝试设置数据的下载/上传,想要数据以易于理解的格式(比如 .csv)呈现——所以使用 bulkloader.py --dump (...) 不是一个可行的选择,因为它给我生成的是 sqlite3 文件,里面的实体内容被压缩成一行。

编辑

我尝试按照 @Nick 的建议去做,但遇到了一个异常:

 ErrorOnTransform: Numeric keys are not supported on input at this time.

这是否意味着我必须坚持使用 bulkloader.py(那个奇怪的 sqlite 格式)或者我搞错了什么?;)

转换器的头部:

- kind: auth_user
    connector: csv
    connector_options:
      encoding: utf-8
      skip_import_header_row: True
      print_export_header_row: True

    property_map:
      - property: __key__
        external_name: key
        export_transform: transform.key_id_or_name_as_string
        import_transform: transform.create_foreign_key('auth_user', key_is_id=True) 

完整的堆栈跟踪:

      Traceback (most recent call last):
      File "/opt/google/appengine/google/appengine/tools/adaptive_thread_pool.py", line 150, in WorkOnItems
        status, instruction = item.PerformWork(self.__thread_pool)
      File "/opt/google/appengine/google/appengine/tools/bulkloader.py", line 693, in PerformWork
        transfer_time = self._TransferItem(thread_pool)
      File "/opt/google/appengine/google/appengine/tools/bulkloader.py", line 848, in _TransferItem
        self.content = self.request_manager.EncodeContent(self.rows)
      File "/opt/google/appengine/google/appengine/tools/bulkloader.py", line 1269, in EncodeContent
        entity = loader.create_entity(values, key_name=key, parent=parent)
      File "/opt/google/appengine/google/appengine/ext/bulkload/bulkloader_config.py", line 385, in create_entity
        return self.dict_to_entity(input_dict, self.bulkload_state)
      File "/opt/google/appengine/google/appengine/ext/bulkload/bulkloader_config.py", line 131, in dict_to_entity
        instance = self.__create_instance(input_dict, bulkload_state_copy)
      File "/opt/google/appengine/google/appengine/ext/bulkload/bulkloader_config.py", line 209, in __create_instance
        'Numeric keys are not supported on input at this time.')

2 个回答

2

这个对我来说很好用:

import_transform: transform.none_if_empty(long)
6

你有一个叫做 export_transform 的东西,名字是 'key_id_or_name_as_string',但是你没有对应的 import transform。可以试试这样:

property_map:
 - property: __key__
   external_name: key
   export_transform: transform.key_id_or_name_as_string
   import_transform: transform.create_foreign_key('Kind', key_is_id=True)

这里的 'Kind' 是在配置文件中定义的种类的名字。

撰写回答