使用bulkloader上传数据

时间:2011-05-09 12:41:17

标签: python google-app-engine bulkloader

简而言之:如何配置bulkloader以将数据插入带引用的2个模型?

我有一个人和水果班,有人联系到水果:

class Fruit(db.Model): 
    name = db.StringProperty()
class Person(db.Model): 
    name = db.StringProperty() 
    customer = db.ReferenceProperty(Fruit)

我想上传此CSV数据:

Name,Fruit
Bob,Banana
Joe,Apple
Tim,Banana

我尝试使用docs中的create_foreign_key:

transformers:

- kind: fruit
  connector: csv
  property_map:
    - property: fruit
      external_name: Fruit

- kind: person
  connector: csv
  connector_options:
    encoding: utf-8
    columns: from_header
  property_map:
    - property: title
      external_name: Name
    - property: fruit
      external_name: Fruit
      import_transform: transform.create_foreign_key('fruit')

当我运行命令时:

appcfg.py upload_data --config_file=bulkloader.yaml --filename=food.csv --kind=person .

这些人被上传,他们有水果的外键,但他们指出的水果实体不存在。

当我尝试--kind=fruit上传水果时,但有很多重复。

我正在尝试将此人与水果联系起来,没有重复的水果 - 这是否可以通过bulkloader进行?

3 个答案:

答案 0 :(得分:4)

不确定

基本问题是缺少一个步骤。你有一个水果名称,你想要存储引用的是一个水果密钥。你可以通过几种方式实现这一目标。

如果BananaApple是水果的永久唯一标识符,则可以使用transform.create_foreign_key('Fruit')。这将为您提供一个水果钥匙,其中水果名称是关键名称。将上传人员指向不存在的Fruit实体,这很好。只需使用__key__属性上的相同导入转换上传水果即可创建相应的实体。

如果您不想使用水果名称作为水果密钥名称,则需要进行一些更复杂的导入后处理。您可以编写一个post_import_function来查询水果的名称,以查看匹配的实体是否已经存在,如果没有则创建一个,然后在新创建的人员实体上设置对它的引用。

答案 1 :(得分:1)

可以使用post_import_function。

在您的模型中,执行导入外键。相反,添加一个类似于:

的post_import_function
def fkeyLocation(input_dict, entity_instance, bulkload_state):
   entity_instance.availableAt =  Location.all().filter('name = ',input_dict['availableAt']).get().key()

   return entity_instance

诀窍是使用input_dict进行查找。如果您正在使用多态代码,则无法使用向导中自动生成的“种类”,您必须使用示例代码here中的model.modelName。

答案 2 :(得分:0)

我没有弄清楚如何干净利落地这样做,所以最终只是将我的数据分成多个文件并预生成ID。