mongoengine
mongoengine copied to clipboard
GenericEmbeddedDocumentField validation errors on .upsert but not on .save
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()