2010-02-25 3 views
1

저는 앱 엔진이있는 대용량 데이터의 경우 CSV 기반 내보내기/가져 오기를 사용했습니다. 제 아이디어는 단순했습니다.은 bulkloader.Loader를 통해 기존 엔티티를 덮어 씁니다.

  • CSV의 첫 번째 열은 엔티티의 핵심입니다.
  • 비어 있지 않으면 해당 행은 기존 엔티티를 의미하며 이전 엔티티를 덮어 써야합니다.
  • 그렇지 않으면 해당 행은 새로운 항목이며 새 항목을 만들어야합니다.

나는 속성을 추가하여 개체의 키를 내보낼 수 있습니다. 내가 CSV를 업로드하려고 할 때 bulkloader.Loader.generate_key()는 그냥 "KEY_NAME"없습니다 "키"자체 때문에

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

, 그것은 실패했다. 즉, CSV에있는 모든 내 보낸 엔티티가 수정 및 다시 업로드하려는 경우 고유 한 'key_name'을 가져야합니다.

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] 

답변

0

최상의 옵션은 아마도 create_entity을 무시하는 것입니다. 거기에있는 대부분의 기존 코드를 복사해야하지만 key_name 인수 대신 key 인수를 제공하도록 생성자를 수정해야합니다.

관련 문제