winwin
winwin

Reputation: 1797

Get __enter__'s return value in __exit__

I'm trying to make a database connection pool behave like a simple connection (psycopg2). Kind of like this:

from psycopg2.pool import ThreadedConnectionPool    
pool = ThreadedConnectionPool(...)
with pool as conn:
    with conn.cursor() as cur:
        # do sql stuff
        ...

To do this, we should conn = pool.getconn() from the pool, and, after we're done with the queries, pool.putconn(conn) it back. Seems like a perfect example of using the context manager.

Yet if we do:

# this function -> a part of ThreadedConnectionPool subclass
def __enter__(self):
    return self._pool.getconn()  # doesn't return self, returns a database connection

Then, you need to return the connection in the __exit__ method. Something like:

# this function -> a part of ThreadedConnectionPool subclass
def __exit__(self, *args):
    self._pool.putconn(conn)  # <--- here!
    ...

but how do we access the conn object? It seems like it should be known to the context, but where can it actually be accessed?

I've read this SO question, but it this object is used in a multithreaded environment and stores a lot of connections simultaneously, so there is no chance we can use a local state variable, is there?

What can one do to access the __enter__ return value in the __exit__ function call?

Upvotes: 0

Views: 178

Answers (1)

Tim Roberts
Tim Roberts

Reputation: 54698

This particular object should only have one connection at a time. So this should work:

    def __enter__(self):
        self.conn = self.__pool.getconn()
        return self.conn
    def __exit__(self, *args):
        self.__pool.putconn(self.conn)
        self.conn = None

Upvotes: 2

Related Questions