Как в Google App Engine настроить bulkloader.yaml для обработки необязательного внешнего ключа в модели?

У меня есть модель в App Engine, которую я экспортирую в формате CSV, а затем импортирую в свою локальную среду разработки, используя appcfg.py и bulkloader.yaml.

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

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

Столбец myOtherModel в CSV-файле иногда содержит MyOtherModel.key().id(), а иногда нет.

Eg.

myOtherModel
1234
4567

2345

5678

person Chris    schedule 23.01.2012    source источник
comment
Они совпадают. Если я помещу идентификатор в столбец для каждого свойства внешнего ключа MyOtherModel в файле CSV для MyModel, все будет работать. Кажется, что я не получаю вариант по умолчанию None.   -  person Chris    schedule 23.01.2012
comment
Ok. Спасибо за попытку. Можете ли вы помочь мне правильно написать эту лямбда-строку? лямбда x: int(x)›0 и x или Создать внешний ключ   -  person Chris    schedule 23.01.2012
comment
Проблема, похоже, в том, что по какой-то причине процесс массовой загрузки пытается проанализировать пробел '' как целое число. Вот почему я пытаюсь просто сделать лямбда-выражение, чтобы я мог поймать несуществующие внешние ключи и предотвратить ошибку. Спасибо за указание на другие проблемы StackOverflow. Я просмотрел их, но ни один из них не связан с возвратом ключей. Мне нужно иметь возможность возвращать create_foreign_key(), когда в столбце присутствует число, но я не могу найти синтаксис.   -  person Chris    schedule 23.01.2012


Ответы (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/ как комментирует Томас Турман, лямбда-выражение должно выглядеть так:

import-transform: "lambda x: [x, None][x=='']"

Я надеюсь, что это сработает для вас

person asdf_enel_hak    schedule 23.01.2012
comment
Нет. В этом проблема. Использование строки transform.create_foreign_key() приведет к ошибке, которую я только что добавил выше. - person Chris; 23.01.2012

Один из способов справиться с этим:

  1. Импортируйте все сущности, у которых нет ключей, с помощью файла bulkloader.yaml, в котором для модели не указано преобразование импорта свойства ключа.

  2. Экспорт всех объектов.

  3. Импортируйте объекты. (все из которых теперь будут иметь ключевые значения)

Немного лучший вариант этого:

  1. Импортируйте все сущности, у которых есть ключи, используя bulkloader.yaml с преобразованием импорта свойства ключа.

  2. Импортируйте все объекты без ключей с помощью bulkloader.yaml без преобразования импорта свойства ключа.

Это немного громоздко. Я хотел бы, чтобы у объектов отсутствовало ключевое значение, автоматически назначаемое при импорте.

person James    schedule 17.06.2013