MongoEngine / MongoEngine/mongoengine
GenericEmbeddedDocumentField validation errors on .upsert but not on .save
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 4.3k
- Forks
- 1.2k
- Avg merge
- 4h 41m
- Merged PRs (30d)
- 11
Description
Hi, I have a document defined with GenericEmbeddedDocumentField field;
class BrandItem(mg.Document):
"""
BrandItems of a brand in the inventory
"""
# inventory name of the brandItem
name = StringField(required=True, unique_with='brand')
# Brand under which the brandItems fall
# If the brand is deleted this brand item will also be deleted
brand = ReferenceField('Brand', reverse_delete_rule=CASCADE)
# item type stores the type of items and item body stores the object of the type
item_type = EnumField(ItemType, required=True)
item_body = GenericEmbeddedDocumentField(required=True)
# Auto update fields
created = DateTimeField(default=datetime.utcnow())
modified = DateTimeField()
is_deleted = BooleanField(default=False)
When trying to save instances of this model I get different behaviours when creating an object and saving (works) and when trying to upsert it via the QuerySet manager (fails).
The error is
mongoengine.errors.ValidationError: Invalid embedded document instance provided to an GenericEmbeddedDocumentField
Interestingly, If I define the document with a DictField the behaviour swaps (upsert works and saves validation complains).
The upsert command:
brand_item_dict = dict(
name="Honey butter",
brand=bid,
is_excluded_from_gp_calculation=False,
category_name="Condiments",
item_type=ItemType.SUPPLIED_ITEM,
item_body=SuppliedItem(
purchasing_info=[
PurchasingInfo(
supplier="Nory Sup",
pack_size=5,
unit_of_measure=UnitOfMeasure.LITRE,
packs_per_case=10,
price=100,
currency=Currency.EURO,
price_unit_type=PriceUnitType.CASE,
is_main_purchasing_order_info=True,
supplier_code="item.supplier_code",
)
]
)
)
res = BrandItem.objects.upsert_one(
**brand_item_dict
)
The "same" command works when creating the brand object directly:
brand_item = BrandItem(
name="Honey butter",
brand=bid,
is_excluded_from_gp_calculation=False,
category_name="Condiments",
item_type=ItemType.SUPPLIED_ITEM,
item_body=SuppliedItem(
purchasing_info=[
PurchasingInfo(
supplier="Nory Sup",
pack_size=5,
unit_of_measure=UnitOfMeasure.LITRE,
packs_per_case=10,
price=100,
currency=Currency.EURO,
price_unit_type=PriceUnitType.CASE,
is_main_purchasing_order_info=True,
supplier_code="item.supplier_code",
)
]
)
)
brand_item.save()
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing the difference between QuerySet.upsert_one and Document.save with GenericEmbeddedDocumentField, using the BrandItem and SuppliedItem examples in the issue. Compare the validation behavior with DictField and determine what consistent validation result should be observed for both paths.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- mongodb, python
- Domain
- database
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100