LordOfTheSnow
LordOfTheSnow

Reputation: 326

mongoengine: update document with date field fails with << self.error('cannot parse date "%s"' % value) >>

Mongoengine is really beginning to be a pain in the a**.

I am querying a document via Python/Mongoengine from a MongoDB collection that contains a creation date.

I converted the whole output with to_json() to a json string

    document = Qkey.objects(id=id)
    djson = document.to_json()

which then contains this:

...
"date_created": {
    "$date": 1595784271766
},
...

I then put the whole JSON structure into a textarea field in a web application to let the user make changes to the JSON data (usually he will not make changes to the "date_created" value but to some other fields).

I read in the whole textarea and convert it back from a large string to a Python dictionary.

As expected, the dictionary item looks like this when being printed:

date_created: {'$date': 1595784271766}

However, when I then try to update() the whole Mongoengine document, I get this error stack:

  File "/webupdate/app/edit.py", line 38, in update_document
    document.update(**attributes_json)
  File "/webupdate/env/lib/python3.6/site-packages/mongoengine/queryset/base.py", line 530, in update
    update = transform.update(queryset._document, **update)
  File "/webupdate/env/lib/python3.6/site-packages/mongoengine/queryset/transform.py", line 317, in update
    value = field.prepare_query_value(op, value)
  File "/webupdate/env/lib/python3.6/site-packages/mongoengine/fields.py", line 593, in prepare_query_value
    return super().prepare_query_value(op, self.to_mongo(value))
  File "/webupdate/env/lib/python3.6/site-packages/mongoengine/base/fields.py", line 196, in prepare_query_value
    self.validate(value)
  File "/webupdate/env/lib/python3.6/site-packages/mongoengine/fields.py", line 536, in validate
    self.error('cannot parse date "%s"' % value)
  File "/webupdate/env/lib/python3.6/site-packages/mongoengine/base/fields.py", line 171, in error
    raise ValidationError(message, errors=errors, field_name=field_name)
mongoengine.errors.ValidationError: cannot parse date "None"

When I remove date_created completely, the update works.

I hope anyone can point me in the right direction how to handle date fields via JSON to Python dicts to update a whole MongoDB document.

Upvotes: 1

Views: 1327

Answers (2)

Marek Piotrowski
Marek Piotrowski

Reputation: 3076

Everywhere in the documentation it appears that a DateTimeField is updated using Python's datetime object. Have you tried converting that timestamp into a datetime in that map used in update_document:

date_created: {'$date': datetime.fromtimestamp(1595784271766) }

Let me know if that helps.

Edit basing on this fragment (lines: 533 - 536 in site-packages/mongoengine/fields.py, mentioned in OP's error) it appears that problem might indeed be with value not being a date or datetime instance:

def validate(self, value):
    new_value = self.to_mongo(value)
    if not isinstance(new_value, (datetime.datetime, datetime.date)):
        self.error('cannot parse date "%s"' % value)

Not sure if self.to_mongo(value) does not return None earlier, though.

Upvotes: 0

D. SM
D. SM

Reputation: 14490

I am not familiar with mongoengine but you appear to have serialized a document to extended json using the to_json call. To reverse this you need to parse extended json into a proper python object structure using for example the method described here. Generally you cannot parse extended json with a plain json parser and use the resulting type-annotated raw document as input to methods that require objects of "normal" language types.

Upvotes: 0

Related Questions