HiveBrain v1.2.0
Get Started
← Back to all entries
snippetpythonCritical

How can I overcome "datetime.datetime not JSON serializable"?

Submitted by: @import:stackoverflow-api··
0
Viewed 0 times
datetimehowjsonnotcanserializableovercome

Problem

sample = {}
sample['title'] = "String"
sample['somedate'] = somedatetimehere


jsonify(sample) on that dict gets:

TypeError: datetime.datetime(2012, 8, 8, 21, 46, 24, 862000) is not JSON serializable

What can I do to overcome that error?

Note: the dictionaries are generated from the retrieval of records out of mongodb where when I print out str(sample['somedate']), the output is 2012-08-08 21:46:24.862000.

Solution

Updated for 2018

The original answer accommodated the way MongoDB "date" fields were represented as:

{"$date": 1506816000000}

If you want a generic Python solution for serializing datetime to json, check out @jjmontes' answer for a quick solution which requires no dependencies.

As you are using mongoengine (per comments) and pymongo is a dependency, pymongo has built-in utilities to help with json serialization:

http://api.mongodb.org/python/1.10.1/api/bson/json_util.html

Example usage (serialization):

from bson import json_util
import json

json.dumps(anObject, default=json_util.default)


Example usage (deserialization):

json.loads(aJsonString, object_hook=json_util.object_hook)


Django

Django provides a native DjangoJSONEncoder serializer that deals with this kind of properly.

See https://docs.djangoproject.com/en/dev/topics/serialization/#djangojsonencoder

from django.core.serializers.json import DjangoJSONEncoder

return json.dumps(
  item,
  sort_keys=True,
  indent=1,
  cls=DjangoJSONEncoder
)


One difference I've noticed between DjangoJSONEncoder and using a custom default like this:

import datetime
import json

def default(o):
    if isinstance(o, (datetime.date, datetime.datetime)):
        return o.isoformat()

return json.dumps(
  item,
  sort_keys=True,
  indent=1,
  default=default
)


Is that Django strips a bit of the data:

"last_login": "2018-08-03T10:51:42.990", # DjangoJSONEncoder 
 "last_login": "2018-08-03T10:51:42.990239", # default


So, you may need to be careful about that in some cases.

Code Snippets

from bson import json_util
import json

json.dumps(anObject, default=json_util.default)
json.loads(aJsonString, object_hook=json_util.object_hook)
from django.core.serializers.json import DjangoJSONEncoder

return json.dumps(
  item,
  sort_keys=True,
  indent=1,
  cls=DjangoJSONEncoder
)
import datetime
import json

def default(o):
    if isinstance(o, (datetime.date, datetime.datetime)):
        return o.isoformat()

return json.dumps(
  item,
  sort_keys=True,
  indent=1,
  default=default
)
"last_login": "2018-08-03T10:51:42.990", # DjangoJSONEncoder 
 "last_login": "2018-08-03T10:51:42.990239", # default

Context

Stack Overflow Q#11875770, score: 560

Revisions (0)

No revisions yet.