Last active
July 28, 2021 23:41
-
-
Save haynesgt/d34bad1cb3d4dd03a04e1d00cd6f8b10 to your computer and use it in GitHub Desktop.
Creates documents for elasticsearch_dsl
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from inspect import isclass | |
import json | |
import sys | |
import elasticsearch_dsl.field | |
def snake_to_camel(word): | |
return ''.join(x.capitalize() or '_' for x in word.split('_')) | |
field_types = ( | |
field_type | |
for typename in dir(elasticsearch_dsl.field) | |
for field_type in (getattr(elasticsearch_dsl.field, typename),) | |
if isclass(field_type) and issubclass(field_type, elasticsearch_dsl.field.Field) | |
) | |
field_types_by_name = { | |
field_type.name: field_type | |
for field_type in field_types | |
} | |
def convert_mapping(class_name, mapping, used_type_names, converted_mappings, parent="Document", index_name=None): | |
mappings_to_convert = [] | |
properties = mapping["properties"] | |
class_body_lines = [] | |
for property_name in properties: | |
field_mapping = properties[property_name] | |
field_type_name = field_mapping.get("type", "object") | |
field_type = field_types_by_name[field_type_name] | |
field_type_class_name = field_type.__name__ | |
if "properties" in field_mapping and field_type_name in ("object", "nested"): | |
object_class_name = f"{class_name}{snake_to_camel(property_name)}" | |
class_body_lines.append(f" {property_name} = {field_type_class_name}({object_class_name})") | |
mappings_to_convert.append({ | |
"class_name": object_class_name, | |
"mapping": field_mapping | |
}) | |
else: | |
type_kwargs = ", ".join(f"{item[0]}=\"{item[1]}\"" for item in field_mapping.items() if item[0] in ["analyzer"]) | |
class_body_lines.append(f""" {property_name} = {field_type_class_name}({type_kwargs})""") | |
used_type_names.add(field_type_class_name) | |
class_body_lines.sort() | |
if index_name: | |
class_body_lines = [ | |
" class Index:", | |
f" name = \"{index_name}\"", | |
*class_body_lines | |
] | |
class_body = f"class {class_name}({parent}):\n" + "\n".join(class_body_lines) | |
for config in mappings_to_convert: | |
convert_mapping(config["class_name"], config["mapping"], used_type_names, converted_mappings, parent="InnerDoc") | |
converted_mappings[class_name] = class_body | |
if __name__ == "__main__": | |
# Get this from http://elasticsearch:9200/* | |
indexes = json.load(sys.stdin) | |
used_type_names = set() | |
converted_mappings = {} | |
for index in indexes: | |
class_name = snake_to_camel(index) | |
convert_mapping(class_name, indexes[index]["mappings"], used_type_names, converted_mappings, index_name=index) | |
imports = ", ".join(sorted(used_type_names)) | |
print("from elasticsearch_dsl import Document, InnerDoc") | |
print(f"from elasticsearch_dsl.field import {imports}") | |
for mapping_name in converted_mappings: | |
print() | |
print() | |
print(converted_mappings[mapping_name]) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment