Wierd jsonpickle.encode behavior

333 Views Asked by At

I'm using jsonpickle as a database for my small project and encountered some weird behavior when encoding a complex class, basically Book from a User instance is encoded correctly but books in db list are encoded as strange {"py/id":4}-s. Could someone please explain where I went wrong and how do I fix this

import jsonpickle
from random import randint

admin_ids = [302115492]

def gen_id():
    return randint(1, 2**64)

class Book():
    def __init__(self, name, author, img, oid):
        self.name = name
        self.author = author
        self.img = img
        self.id = gen_id()
        self.owner_id = oid

class User():
    id = 0
    name = ""
    books = []
    requests = []

    def __init__(self, name, uid):
        self.id = uid
        self.name = name
        self.books = []

class Database():
    def __init__(self):
        self.u_dir = "users"
        self.b_dir = "books"
        self.users = []
        self.books = []
    
    def add_book(self, book):
        self.books.append(book)
        for user in self.users:
            if(user.id == book.owner_id):
                user.books.append(book)
    
    def add_user(self, user):
        self.users.append(user)

db=Database()
db.add_user(User('John',123))
db.add_book(Book('name','author','img.png',123))
print(jsonpickle.encode(db))

Output:

{
   "py/object":"__main__.Database",
   "u_dir":"users",
   "b_dir":"books",
   "users":[
      {
         "py/object":"__main__.User",
         "id":123,
         "name":"John",
         "books":[
            {
               "py/object":"__main__.Book",
               "name":"name",
               "author":"author",
               "img":"img.png",
               "id":8045585124766781176,
               "owner_id":123
            }
         ]
      }
   ],
   "books":[
      {
         "py/id":4
      }
   ]
}
1

There are 1 best solutions below

0
On

So apparently jsonpickle uses this id thing to compactly store objects that are already stored somewhere inside object's encoding. To store all objects explicitly one can use make_refs flag when encoding. In the code above it would look like this: print(jsonpickle.encode(db), make_refs=False)