Search code examples
pythonelasticsearchkeyword-argumentsetattrelasticsearch-dsl

Dynamically generated DocType in Elasticsearch DSL


I am generating a DocType class for building mapping and saving documents based upon my ORM.

def get_doc_type(self):
    attributes = {}

    ...
    # Build attributes dictionary here

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

This seemingly works fine and I have no troubles with mapping. My problem is when I try to save documents.

THIS DOES NOT WORK

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)

When this happens, a document does get saved, however, none of my attributes are set. It is just an empty document.

I have debugged the code to confirm that the field_name and attribute contain the values I would expect.

THIS DOES WORK

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)

When I use this strategy, the document is saved as expected, and all the information and attributes have been passed from my instance into the doc.

QUESTION

What could be causing this? It does not make sense to me why both strategies would not be valid.


Solution

  • In your case I guess, it must have some more info for the save() method to know which field_name should be stored.

    Maybe like this:

        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 you should look into both the __init__ and save methods in the Doc class to find out what actually it does to persist the Doc object.