Avoid jsonpickle using py/id pointer to another object
Asked Answered
M

4

8

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"}}

Mckamey answered 22/1, 2018 at 22:9 Comment(0)
S
8

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.

Schram answered 4/2, 2018 at 22:51 Comment(0)
H
10

New way of doing. Above answer is old.

jsonpickle.encode(my_object, unpicklable=False)

Hakon answered 28/8, 2020 at 11:57 Comment(1)
If you will never need to load (regenerate the Python class from JSON), you can pass in the keyword unpicklable=False to prevent extra information from being added to JSON. Adam's answer should be the correct one, instead.Sarrusophone
S
8

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.

Schram answered 4/2, 2018 at 22:51 Comment(0)
C
5

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.

Caffrey answered 17/8, 2022 at 8:20 Comment(0)
E
0

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)
Epsilon answered 14/10, 2021 at 15:34 Comment(1)
OK, but what's the difference between unpickable=False and make_refs=False?Feminine

© 2022 - 2024 — McMap. All rights reserved.