Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to assign custom field names to Document fields #1659

Open
deniz-dilaverler opened this issue Aug 18, 2023 · 3 comments
Open

How to assign custom field names to Document fields #1659

deniz-dilaverler opened this issue Aug 18, 2023 · 3 comments

Comments

@deniz-dilaverler
Copy link

We are trying to use the Documents API to connect with our existing Elasticsearch server however, we have a convention of prefixing our field names with '@' ("field1" = "value" is persisted as "@field1" = "value"). What we are looking for is a way to define custom names to properties as such:

class SampleDoc(BaseDocument):
    field1 = Keyword(name="@field1")
    field2 = Integer(name="@field2")

    class Index:
        name = "sample-doc"

The current way we are approaching this problem is by overriding the parent to_dict() method with the same to_dict method with just the key name adjusted.

class BaseDocument(Document):
    def to_dict(self, include_meta=False, skip_empty=True):
        d = self._serialize(skip_empty=skip_empty)
        if not include_meta:
            return d

        meta = {"_" + k: self.meta[k] for k in DOC_META_FIELDS if k in self.meta}

        # in case of to_dict include the index unlike save/update/delete
        index = self._get_index(required=False)
        if index is not None:
            meta["_index"] = index

        meta["_source"] = d
        return meta

    def _serialize(self, skip_empty=True):
        out = {}
        for k, v in self._d_.items():
            # if this is a mapped field,
            try:
                f = self._doc_type.mapping[k]
            except KeyError:
                pass
            else:
                if f and f._coerce:
                    v = f.serialize(v)

            # if someone assigned AttrList, unwrap it
            if isinstance(v, AttrList):
                v = v._l_

            if skip_empty:
                # don't serialize empty values
                # careful not to include numeric zeros
                if v in ([], {}, None):
                    continue

            out[f"@{k}"] = v
        return out

However, this solution isn't the most favorable way of doing this while working on the init() and save() methods it may result in problems with the other methods of the class in the future. Is there a better way of doing this or a future plan to support custom field names?

@deniz-dilaverler
Copy link
Author

@honzakral can you help me?

@honzakral
Copy link
Contributor

I am sorry, but there is no better way of doing it. By prefixing fields with @ you have practically disabled any functionality of the DSL library which tries to treat documents/fields in a pythonic way. There is just no way to treat something that is not a valid python identifier as a python object.

Introducing possible aliases would be a way but currently there is no one maintaining the library. See #1652

@miguelgrinberg
Copy link
Collaborator

Also mentioned in #1345

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants