Загрузка данных с помощью загрузчика - PullRequest
3 голосов
/ 09 мая 2011

Вкратце: как я могу настроить загрузчик для вставки данных в 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

Я пытался использовать 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, фрукты загружаются, но естьмного дубликатов.

Я пытаюсь связать человека с фруктами, без дубликатов фруктов - возможно ли это через оптовый загрузчик?

Ответы [ 3 ]

4 голосов
/ 09 мая 2011

Конечно.

Основная проблема в том, что отсутствует шаг. У вас есть фруктовое название, ссылка на который вы хотите сохранить - это фруктовый ключ. Вы можете сделать это несколькими способами.

Если Banana или Apple - это постоянный уникальный идентификатор фрукта, вы можете использовать transform.create_foreign_key('Fruit'). Это даст вам фруктовый ключ, где фруктовое имя - это ключевое имя. Люди будут загружены, указывая на сущности Fruit, которые не существуют, и это нормально. Просто загрузите фрукты с помощью того же преобразования импорта в свойстве __key__, чтобы создать соответствующие объекты.

Если вы не хотите использовать имя фрукта в качестве имени ключа фрукта, вам необходимо выполнить более сложную обработку после импорта. Вы можете написать post_import_function, который запрашивает фрукты по имени, чтобы увидеть, существует ли соответствующая сущность, создает ее, если нет, и затем устанавливает ссылку на нее для вновь созданной сущности.

1 голос
/ 19 августа 2011

Это возможно с функцией post_import_.

В вашей модели не импортируйте внешний ключ. Вместо этого добавьте функцию 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. Если вы используете полимодели, вы не можете использовать автоматически сгенерированный «вид» из мастера, вы должны использовать модель.modelName из примера кода здесь .

0 голосов
/ 16 мая 2011

Я не понял, как это сделать чисто, поэтому в итоге я просто разбил свои данные на несколько файлов и предварительно сгенерировал идентификаторы.

...