2010-02-25 28 views
1

我正在使用基於CSV的導出/導入大型數據與應用程序引擎。我的想法很簡單。通過bulkloader覆蓋現有的實體。加載器

  • CSV的第一列將是實體的關鍵。
  • 如果不是空的,該行意味着現有的實體,並應覆蓋舊的實體。
  • 否則,該行是新的實體,應該創建一個新的實體。

我可以通過添加密鑰屬性來導出實體的密鑰。

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」而不是「關鍵」本身。這意味着如果我想修改並重新上傳它們,所有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而不是key_name參數。