2016-12-24 55 views
1

我正在生成一個DocType類,以根據我的ORM構建映射和保存文檔。在Elasticsearch DSL中動態生成DocType

def get_doc_type(self): 
    attributes = {} 

    ... 
    # Build attributes dictionary here 

    DT = type('DocType', (DocType,), attributes) 
    return DT 

這看似工作正常,我沒有映射的麻煩。我的問題是當我試圖保存文件。

這不起作用

Doc = get_doc_type() 

for instance in queryset: 
    doc = Doc() 
    for field_name in fields: 
     attribute = getattr(instance, field_name, None) 
     setattr(doc, field_name, attribute) 
    doc.save(index) 

發生這種情況時,文檔確實得到保存,但是,沒有我的屬性被設置。它只是一個空文件。

我已調試代碼以確認field_nameattribute包含我期望的值。

這樣確實

Doc = self.get_doc_type() 

for instance in queryset: 
    kwargs = {} 

    for field_name in fields: 
     attribute = getattr(instance, field_name, None) 
     kwargs.update({field_name: attribute}) 

    doc = Doc(**kwargs) 
    doc.save(index=index) 

當我使用這個策略,預期該文件被保存,所有的信息和attributes已經從我的instance傳遞到doc

問題

可能是什麼造成的?這對我來說沒有意義,爲什麼兩種策略都無效。

回答

1

在你的情況下,我想,它必須有一些save()方法的更多信息知道應該存儲哪些field_name

也許是這樣的:

class Doc(object): 
     def __init__(self, **kwargs): 
      self.fields_valid = kwargs.copy() 
      ... 
     ... 
     def save(self, index=None): 
      ... 
      for field in self.fields_valid: 
       do_save(field) 
      .... 

那麼你應該考慮在文檔類__init__save方法都以找出究竟它堅持的文檔對象。我有麻煩

1

複製你的行爲作爲一切工作對我來說只是罰款:

class DT(DocType): 
    pass 

dt = DT() 

for x in range(10): 
    setattr(dt, 'i_%i' % x, x) 
dt.save() 

DT.search().execute()[0].to_dict() 

顯示正是我本來期望。你可以請github上的問題,如果它不適合你,因爲在這種情況下是錯誤的。謝謝!

順便說一句我通常從ORM序列化爲elaasticsearch-dsl時做的是直接有to_search或類似的方法上,其產生DocType實例Model。它使一切變得如此簡單,包括使用信號同步兩個數據集。

+0

這基本上就是我所做的。我做了一個模型管理器作爲django管理器的子類(這是我的方法生成類的地方)。我試圖避免爲每個模型創建一個新類,而是隻能添加我的mixin。當不使用'type'來生成一個類時,它似乎工作正常。 –