【问题标题】:Dynamically generated DocType in Elasticsearch DSLElasticsearch DSL 中动态生成的 DocType
【发布时间】:2016-12-24 21:01:47
【问题描述】:

我正在生成一个DocType 类,用于基于我的 ORM 构建映射和保存文档。

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

问题

这可能是什么原因造成的?我不明白为什么这两种策略都无效。

【问题讨论】:

    标签: python elasticsearch keyword-argument setattr elasticsearch-dsl


    【解决方案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 时,我通常会在 Model 上直接使用 to_search 或类似方法来生成 DocType 实例。它让一切变得如此简单,包括使用信号同步两个数据集。

    【讨论】:

    • 这基本上就是我所做的。我已经将模型管理器作为 django 管理器的子类(这是我生成该类的方法所在的位置)。我试图避免为每个模型创建一个新类,而是能够添加我的 mixin。当不使用type 生成类时,它似乎工作正常。
    【解决方案2】:

    在你的情况下,我猜,它必须有更多信息让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)
                ....
    

    因此,您应该同时查看 Doc 类中的 __init__save 方法,以了解它实际上是如何持久化 Doc 对象的。

    【讨论】:

      猜你喜欢
      • 2019-04-01
      • 2016-04-24
      • 1970-01-01
      • 2016-02-18
      • 2016-11-26
      • 2021-08-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多