Reputation: 2345
When an object is serialized to json using jsonpickle, I noticed objects such as datetime are stored once then future uses are stored as references value such as {"py/id":1}
. Is it possible store actual value instead of reference? This reference seems hidden and would be confusing when interacting directly with database.
Ex.
class MyClass:
def __init__(self, eee):
now = datetime.datetime.utcnow()
self.ddd = now
self.ddd2 = now
self.ddd3 = now
Json is
{"py/object": "__main__.MyClass", "py/state": {"ddd": {"py/object": "datetime.datetime", "__reduce__": [{"py/type": "datetime.datetime"}, ["B+IBFhYJCwx9oQ=="]]}, "ddd2": {"py/id": 1}, "ddd3": {"py/id": 1}, "eee": "fwaef"}}
Upvotes: 8
Views: 5430
Reputation: 311
One should understand the difference between make_refs=False
and unpicklable=False
when trying to simplify the jsonpickle encoding output:
make_refs=False
will prevent jsonpickle from creating references (those py/id
attributes) to identical objects. The references make the output more compact, but less readable, and thus one might prefer make_refs=False
at the expense of a larger file. However, the resulting file can still be decoded back to a Python object.
unpicklable=False
means literally that the jsonpickle output cannot be unpickled, i.e. decoded, to its original type. The output is again more readable, but if the object you're encoding contains non-native datatypes (i.e. classes defined by you), the encoding output will store the value of those objects' properties, but if you try to decode the file back to its python representation, the objects will be dicts, not instances of your classes.
Upvotes: 5
Reputation: 124
Try to use unpicklable attrubute set as False
import datetime
import jsonpickle
class MyClass:
def __init__(self, eee):
now = datetime.datetime.utcnow()
self.ddd = now
self.ddd2 = now
self.ddd3 = now
my_object = MyClass('hi')
jsonpickle.encode(my_object, unpicklable=False)
Upvotes: 0
Reputation: 695
New way of doing. Above answer is old.
jsonpickle.encode(my_object, unpicklable=False)
Upvotes: 10
Reputation: 486
You can use the make_refs
parameter when invoking jsonpickle.encode
:
import datetime
import jsonpickle
class MyClass:
def __init__(self, eee):
now = datetime.datetime.utcnow()
self.ddd = now
self.ddd2 = now
self.ddd3 = now
my_object = MyClass('hi')
jsonpickle.encode(my_object, make_refs=False)
From the documentation here:
make_refs – If set to False jsonpickle’s referencing support is disabled. Objects that are id()-identical won’t be preserved across encode()/decode(), but the resulting JSON stream will be conceptually simpler. jsonpickle detects cyclical objects and will break the cycle by calling repr() instead of recursing when make_refs is set False.
Upvotes: 8