Coverage for portality / lib / es_data_mapping.py: 97%
34 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-05-05 00:09 +0100
« prev ^ index » next coverage.py v7.13.5, created at 2026-05-05 00:09 +0100
1# -*- coding: UTF-8 -*-
2""" Create mappings from models """
4# ~~ESMappings:Library->Elasticsearch:Technology~~
5# ~~->Seamless:Library~~
6# ~~->DataObj:Library~~
8from portality.lib import plugin
11def get_mappings(app):
12 """Get the full set of mappings required for the app"""
14 # LEGACY DEFAULT MAPPINGS
15 mappings = app.config["MAPPINGS"]
17 # Ensure legacy mappings also respect any DEFAULT_INDEX_SETTINGS override (e.g. from test.cfg),
18 # rather than using the hardcoded dict reference set at module import time in settings.py.
19 default_settings = app.config.get("DEFAULT_INDEX_SETTINGS", {})
20 for key in list(mappings.keys()):
21 if 'settings' in mappings[key]:
22 mappings[key]['settings'] = default_settings
24 # TYPE SPECIFIC MAPPINGS
25 # get the list of classes which carry the type-specific mappings to be loaded
26 mapping_daos = app.config.get("ELASTIC_SEARCH_MAPPINGS", [])
28 # load each class and execute the "mappings" function to get the mappings that need to be imported
29 for cname in mapping_daos:
30 klazz = plugin.load_class_raw(cname)
31 mappings[klazz.__type__] = {'mappings': klazz().mappings()}
32 mappings[klazz.__type__]['settings'] = app.config["DEFAULT_INDEX_SETTINGS"]
34 return mappings
37def apply_mapping_opts(field_name, path, spec, mapping_opts):
38 dot_path = '.'.join(path + (field_name,))
39 if dot_path in mapping_opts.get('exceptions', {}):
40 return mapping_opts['exceptions'][dot_path]
41 elif spec['coerce'] in mapping_opts['coerces']:
42 return mapping_opts['coerces'][spec['coerce']]
43 else:
44 # We have found a data type in the struct we don't have a map for to ES type.
45 raise Exception("Mapping error - no mapping found for {}".format(spec['coerce']))
48def create_mapping(struct, mapping_opts, path=()):
49 result = {"properties": {}}
51 for field, spec in struct.get("fields", {}).items():
52 result["properties"][field] = apply_mapping_opts(field, path, spec, mapping_opts)
54 for field, spec in struct.get("lists", {}).items():
55 if "coerce" in spec:
56 result["properties"][field] = apply_mapping_opts(field, path, spec, mapping_opts)
58 for struct_name, struct_body in struct.get("structs", {}).items():
59 result["properties"][struct_name] = create_mapping(struct_body, mapping_opts, path + (struct_name,))
61 dotpath = '.'.join(path)
62 for field, additional_mapping in mapping_opts.get("additional_mappings", {}).items():
63 if field.startswith(dotpath) and "." not in field[len(dotpath) + 1:]:
64 result["properties"][field[len(dotpath):]] = additional_mapping
66 return result