перезаписать существующую сущность через bulkloader.Loader - PullRequest
1 голос
/ 25 февраля 2010

Я собирался в CSV-экспорт / импорт больших данных с помощью механизма приложений. Моя идея была просто проста.

  • Первый столбец CSV будет ключом сущности.
  • Если она не пустая, эта строка означает существующую сущность и должна перезаписать старую.
  • Иначе, эта строка является новой сущностью и должна создать новую.

Я мог бы экспортировать ключ сущности, добавив свойство key .

class FrontExporter(bulkloader.Exporter):
    def __init__(self):
        bulkloader.Exporter.__init__(self, 'Front', [
        ('__key__', str, None),
        ('name', str, None),
        ])

Но когда я пытался загрузить CSV, это не удалось, потому что bulkloader.Loader.generate_key () был только для "key_name", а не для "key". Это означает, что все экспортируемые объекты в CSV должны иметь уникальное имя ключа, если я хочу изменить и повторно загрузить их.

class FrontLoader(bulkloader.Loader):
    def __init__(self):
        bulkloader.Loader.__init__(self, 'Front', [
        ('_UNUSED', lambda x: None),
        ('name', lambda x: x.decode('utf-8')),
        ])
    def generate_key(self,i,values):
        # first column is key
        keystr = values[0]
        if len(keystr)==0:
            return None
        return keystr

Я также пытался загрузить ключ напрямую, не используя generate_key (), но оба не удалось.

class FrontLoader(bulkloader.Loader):
    def __init__(self):
        bulkloader.Loader.__init__(self, 'Front', [
        ('Key', db.Key), # not working. just create new one. 
        ('__key__', db.Key), # same...

Итак, как мне перезаписать существующую сущность, у которой нет «key_name»? Было бы ужасно, если бы я дал уникальное имя всем сущностям .....


С первого ответа я мог справиться с этой проблемой. :)

def create_entity(self, values, key_name=None, parent=None):
  # if key_name is None:
  #     print 'key_name is None'
  # else:
  #     print 'key_name=<',key_name,'> : length=',len(key_name)
  Validate(values, (list, tuple))
  assert len(values) == len(self._Loader__properties), (
      'Expected %d columns, found %d.' %
      (len(self._Loader__properties), len(values)))

  model_class = GetImplementationClass(self.kind)

  properties = {
      'key_name': key_name,
      'parent': parent,
      }
  for (name, converter), val in zip(self._Loader__properties, values):
    if converter is bool and val.lower() in ('0', 'false', 'no'):
      val = False
    properties[name] = converter(val)

  if key_name is None:
      entity = model_class(**properties)
      #print 'create new one'
  else:
      entity = model_class.get(key_name)
      for key, value in properties.items():
          setattr(entity, key, value)
      #print 'overwrite old one'
  entities = self.handle_entity(entity)

  if entities:
    if not isinstance(entities, (list, tuple)):
      entities = [entities]

    for entity in entities:
      if not isinstance(entity, db.Model):
        raise TypeError('Expected a db.Model, received %s (a %s).' %
                        (entity, entity.__class__))

  return entities

def generate_key(self,i,values):
    # first column is key
    if values[0] is None or values[0] in ('',' ','-','.'):
        return None
    return values[0]

1 Ответ

0 голосов
/ 25 февраля 2010

Ваш лучший вариант - переопределить create_entity . Вам нужно будет скопировать большую часть существующего кода туда, но измените конструктор, указав аргумент key вместо аргумента key_name.

...