Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to load ghosted objects with ZODB in python?

I am writing a REST interface with flask in python using ZODB for a storage.

This is my code for GET method:

@app.get("/queues")
def get_queues():
    connection = db.open()
    root = connection.root
    if (hasattr(root, QUEUES_COLLECTION)):
        myQueues = root()[QUEUES_COLLECTION].values()
        #for obj in myQueues:
        #    print(obj.title)
        jsonQueues = orjson.dumps([obj.__dict__ for obj in myQueues])
        connection.close()
        return jsonQueues
    connection.close()
    return "ERROR no queues"

When accessing [ipaddress]:[port]/queues I get [{}{}] as a response, which is due to ZODB loading objects as ghosts. I know I can load them by iterating through collection and accessing attributes (as shown within code comments), but is there a better way?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

You are correct. ZODB initially loads objects as "ghosts" to optimize memory usage. These ghosts are placeholders for the actual object data and they become activated when you access an attribute.

But iterating over all the objects to access their attributes is not the most efficient way if you only need some objects from your collection.

ZODB offers the _p_activate() method to activate a ghost without accessing any of its attributes. If you know you need to work with all objects in a collection, you can explicitly call this method on each one like:

@app.get("/queues")
def get_queues():
    connection = db.open()
    root = connection.root
    if hasattr(root, QUEUES_COLLECTION):
        myQueues = root()[QUEUES_COLLECTION].values()
        for obj in myQueues:
            obj._p_activate()  # explicitly activate each object
        jsonQueues = orjson.dumps([obj.__dict__ for obj in myQueues])
        connection.close()
        return jsonQueues
    connection.close()
    return "ERROR no queues"
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading