Skip to content

Commit 6df6d11

Browse files
committed
Always foallback to fields from Index
1 parent 69f5ca2 commit 6df6d11

File tree

2 files changed

+45
-42
lines changed

2 files changed

+45
-42
lines changed

Changelog.rst

+2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ Changelog
88

99
* Fixed logic around defining a different ``doc_type`` name.
1010
* Added ``retry_on_conflict`` parameter to ``Document.update``.
11+
* fields defined on an index are now used to (de)serialize the data even when not
12+
defined on a ``Document``
1113

1214
6.2.1 (2018-07-03)
1315
------------------

elasticsearch_dsl/utils.py

+43-42
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,39 @@ def __init__(self, meta=None, **kwargs):
355355

356356
super(ObjectBase, self).__init__(kwargs)
357357

358+
@classmethod
359+
def __list_fields(cls):
360+
"""
361+
Get all the fields defined for our class, if we have an Index, try
362+
looking at the index mappings as well, mark the fields from Index as
363+
optional.
364+
"""
365+
for name in cls._doc_type.mapping:
366+
field = cls._doc_type.mapping[name]
367+
yield name, field, False
368+
369+
if hasattr(cls.__class__, '_index'):
370+
if not cls._index._mapping:
371+
return
372+
for name in cls._index._mapping:
373+
# don't return fields that are in _doc_type
374+
if name in cls._doc_type.mapping:
375+
continue
376+
field = cls._index._mapping[name]
377+
yield name, field, True
378+
379+
@classmethod
380+
def __get_field(cls, name):
381+
try:
382+
return cls._doc_type.mapping[name]
383+
except KeyError:
384+
# fallback to fields on the Index
385+
if hasattr(cls, '_index') and cls._index._mapping:
386+
try:
387+
return cls._index._mapping[name]
388+
except KeyError:
389+
pass
390+
358391
@classmethod
359392
def from_es(cls, hit):
360393
meta = hit.copy()
@@ -367,10 +400,10 @@ def from_es(cls, hit):
367400
data[k] = v
368401

369402
doc = cls(meta=meta)
370-
m = cls._doc_type.mapping
371403
for k, v in iteritems(data):
372-
if k in m and m[k]._coerce:
373-
v = m[k].deserialize(v)
404+
f = cls.__get_field(k)
405+
if f and f._coerce:
406+
v = f.deserialize(v)
374407
setattr(doc, k, v)
375408
return doc
376409

@@ -386,27 +419,15 @@ def __getattr__(self, name):
386419
try:
387420
return super(ObjectBase, self).__getattr__(name)
388421
except AttributeError:
389-
if name in self._doc_type.mapping:
390-
f = self._doc_type.mapping[name]
391-
if hasattr(f, 'empty'):
392-
value = f.empty()
393-
if value not in SKIP_VALUES:
394-
setattr(self, name, value)
395-
value = getattr(self, name)
396-
return value
422+
f = self.__get_field(name)
423+
if hasattr(f, 'empty'):
424+
value = f.empty()
425+
if value not in SKIP_VALUES:
426+
setattr(self, name, value)
427+
value = getattr(self, name)
428+
return value
397429
raise
398430

399-
def __get_field(self, name):
400-
try:
401-
return self._doc_type.mapping[name]
402-
except KeyError:
403-
# fallback to fields on the Index
404-
if hasattr(self, '_index') and self._index._mapping:
405-
try:
406-
return self._index._mapping[name]
407-
except KeyError:
408-
pass
409-
410431
def to_dict(self, skip_empty=True):
411432
out = {}
412433
for k, v in iteritems(self._d_):
@@ -428,26 +449,6 @@ def to_dict(self, skip_empty=True):
428449
out[k] = v
429450
return out
430451

431-
def __list_fields(self):
432-
"""
433-
Get all the fields defined for our class, if we have an Index, try
434-
looking at the index mappings as well, mark the fields from Index as
435-
optional.
436-
"""
437-
for name in self._doc_type.mapping:
438-
field = self._doc_type.mapping[name]
439-
yield name, field, False
440-
441-
if hasattr(self, '_index'):
442-
if not self._index._mapping:
443-
return
444-
for name in self._index._mapping:
445-
# don't return fields that are in _doc_type
446-
if name in self._doc_type.mapping:
447-
continue
448-
field = self._index._mapping[name]
449-
yield name, field, True
450-
451452
def clean_fields(self):
452453
errors = {}
453454
for name, field, optional in self.__list_fields():

0 commit comments

Comments
 (0)