Skip to content

EmbeddedDocumentField errors during update when adding new field to DynamicEmbeddedDocument #2486

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

Open
mcsimps2 opened this issue Mar 4, 2021 · 0 comments · May be fixed by #2882
Open

EmbeddedDocumentField errors during update when adding new field to DynamicEmbeddedDocument #2486

mcsimps2 opened this issue Mar 4, 2021 · 0 comments · May be fixed by #2882

Comments

@mcsimps2
Copy link
Contributor

mcsimps2 commented Mar 4, 2021

Summary: When using a DynamicEmbeddedDocument, an InvalidQueryError occurs if you try to set a field that is not defined in the MongoEngine schema. This invalidates the purpose of a dynamic document.

Example:

class B(DynamicEmbeddedDocument):
   foo = StringField()

class A(Document):
  b = EmbeddedDocumentField(B)

# This works
A.objects(...).update(set__b__foo="123")

# This does not work
A.objects(...).update(set__b__bar="123")
# mongoengine.errors.InvalidQueryError: Cannot resolve field "bar"

Solution:
In my custom fork of MongoEngine, I've updated the EmbeddedDocumentField to account for dynamic documents as such.

class EmbeddedDocumentField(BaseField):
      def lookup_member(self, member_name):
        doc_and_subclasses = [self.document_type] + self.document_type.__subclasses__()
        for doc_type in doc_and_subclasses:
            field = doc_type._fields.get(member_name)
            if field:
                return field
        # NEW CODE
        if member_name not in ("S", "$") and any(issubclass(doc_type, DynamicEmbeddedDocument) for doc_type in doc_and_subclasses):
           return DynamicField(db_field=member_name)

Custom Situation: I encountered this error because I had a EmbeddedDocumentListField of DynamicEmbeddedDocuments and I was trying to perform array operators like so:

A.objects(b__foo="abc").modify(set__list_of_b__S__bar="123")

If the maintainers find my solution acceptable, I would be happy to write tests and make a PR with it. Otherwise, I will defer to coders with greater expertise in this codebase for the proper strategy here.

@mcsimps2 mcsimps2 changed the title DynamicEmbeddedDocument errors during update/modify DynamicEmbeddedDocument errors during update when adding new field Mar 4, 2021
@mcsimps2 mcsimps2 changed the title DynamicEmbeddedDocument errors during update when adding new field EmbeddedDocumentField errors during update when adding new field to DynamicEmbeddedDocument Mar 4, 2021
mcsimps2 added a commit to mcsimps2/mongoengine that referenced this issue Mar 4, 2021
In order to allow setting new fields on dynamic embedded documents that previously did not exist, the `lookup_member` function returns dynamic fields as appropriate. This enables operations like `A.objects(...).update(foo__newfield="bar")`.

Resolves MongoEngine#2486
mcsimps2 added a commit to mcsimps2/mongoengine that referenced this issue Apr 10, 2025
In order to allow setting new fields that did not previouly exist on dynamic embedded documents, the `lookup_member` functions on `EmbeddedDocumentField` and `GenericEmbeddedDocumentField` return dynamic fields as appropriate. This enables operations like `A.objects(...).update(foo__newfield="bar")`.

Resolves MongoEngine#2486
mcsimps2 added a commit to mcsimps2/mongoengine that referenced this issue Apr 10, 2025
In order to allow setting new fields that did not previouly exist on dynamic embedded documents, the `lookup_member` functions on `EmbeddedDocumentField` and `GenericEmbeddedDocumentField` return dynamic fields as appropriate. This enables operations like `A.objects(...).update(foo__newfield="bar")`.

Resolves MongoEngine#2486
@mcsimps2 mcsimps2 linked a pull request Apr 10, 2025 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant