Read/get objects from ZODB with closing objects after read

125 views Asked by At

I am trying to standardize getting objects from the database by writing CRUD methods for it. My get method:

@staticmethod
def get_record(tree_name: str, uuid: str):
    """! Get method for records in the DB.
    @param tree_name name of the OOBTree tree for the record
    @param uuid unique id of the record
    @return DB record if found, None otherwise
    """
    with db.transaction() as conn:
        return conn.root()[tree_name].get(uuid)

This throws ZODB.POSException.ConnectionStateError: Shouldn't load state for _____ when the connection is closed meaning it closed the connection before having a chance to copy the value and return it?

The following however works, but I am unsure if I need to close the database at some point since this will leave it open. The app audience should be large so I don't want to create but not release connections.

@staticmethod
def get_record(tree_name: str, uuid: str):
    """! Get method for records in the DB.
    @param tree_name name of the OOBTree tree for the record
    @param uuid unique id of the record
    @return DB record if found, None otherwise
    """
    conn = db.open()
    return conn.root()[tree_name].get(uuid)

Is there any way to use the Context (with statement) to copy the object, which I am not going to modify instead of creating a DB connection each time?

1

There are 1 answers

1
toppk On

This is a question of design. Who is responsible for the database connection? This library, or the callers of the library. You can make the method handle both situations with a optional connection, but it is very reasonable to make methods like this require the database connection to be passed in. Here is an example of your method with an optional connection.

@staticmethod
def get_record(tree_name: str, uuid: str, conn: Optional[ZODB.Connection]):
    """! Get method for records in the DB.
    @param tree_name name of the OOBTree tree for the record
    @param uuid unique id of the record
    @return DB record if found, None otherwise
    """
    should_close = false
    if not conn:
        conn = db.open()
        should_close = true
    uuid = conn.root()[tree_name].get(uuid)
    if should_close:
        conn.close()
    return uuid