2016-12-24 7 views
1

Ich erzeuge eine DocType Klasse zum Erstellen von Mappings und Speichern von Dokumenten basierend auf meinem ORM.Dynamisch generierter DocType in Elasticsearch DSL

def get_doc_type(self): 
    attributes = {} 

    ... 
    # Build attributes dictionary here 

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

Dies scheint funktioniert gut und ich habe keine Probleme mit der Zuordnung. Mein Problem ist, wenn ich versuche, Dokumente zu speichern.

dies nicht funktioniert

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) 

Wenn dies geschieht, wird ein Dokument tut gerettet werden, aber keiner meiner Attribute gesetzt. Es ist nur ein leeres Dokument.

Ich habe den Code überprüft, um zu bestätigen, dass die field_name und die Werte enthalten, die ich erwarten würde.

Das funktioniert

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) 

Wenn ich diese Strategie, das Dokument gespeichert wird, wie erwartet, und alle Informationen und attributes haben von meinem instance in die doc verabschiedet.

FRAGE

Was dies verursachen könnte? Es macht für mich keinen Sinn, warum beide Strategien nicht gültig sind.

Antwort

1

In Ihrem Fall, ich denke, es muss einige weitere Informationen für die save() Methode zu wissen, welche field_name sollte gespeichert werden.

Vielleicht so:

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) 
      .... 

So sollten Sie beide schauen in die __init__ und save Methoden in der Doc-Klasse, um herauszufinden, was es tatsächlich tut das Doc-Objekt zu bestehen.

1

Ich habe Probleme replizieren Ihr Verhalten als alles, was für mich funktioniert gut:

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() 

genau zeigt, was ich erwartet hätte. Könnten Sie bitte ein Problem auf GitHub einreichen, wenn es für Sie nicht funktioniert, da in diesem Fall etwas nicht stimmt. Vielen Dank!

BTW, was ich tun normalerweise auf, wenn von einem ORM in elaasticsearch-dsl Serialisierung ist ein to_search oder ähnliche Verfahren zu haben, direkt auf dem ModelDocType, die eine Instanz erzeugt. Es macht alles so viel einfacher, einschließlich der Synchronisierung der beiden Datensätze mit Signalen.

+0

Das ist im Grunde, was ich getan habe. Ich habe einen Modellmanager als eine Unterklasse des Django-Managers gemacht (wo meine Methode, die die Klasse generiert, ist). Ich wollte vermeiden, dass ich für jedes Modell eine neue Klasse erstellen musste, und stattdessen einfach mein Mixin hinzufügen. Wenn Sie 'type' NICHT verwenden, um eine Klasse zu generieren, scheint es zu funktionieren. –

Verwandte Themen