# Connection pooling with psycopg2
In this chapter we'll look at replacing our create_connection()
function with a connection pool.
Our model class methods that use create_connection()
will instead get a connection from the pool, and put it back into the pool when they're done (instead of closing the connection).
# Creating the connection pool
I'm going to start by creating a file called connection_pool.py
.
This is how we can create a simple connection pool that is not thread-safe[1]:
import os
from psycopg2.pool import SimpleConnectionPool
from dotenv import load_dotenv
DATABASE_PROMPT = "Enter the DATABASE_URI value or leave empty to load from .env file: "
database_uri = input(DATABASE_PROMPT)
if not database_uri:
load_dotenv()
database_uri = os.environ["DATABASE_URI"]
pool = SimpleConnectionPool(minconn=1, maxconn=10, dsn=database_uri)
As you can see, I've:
- imported
SimpleConnectionPool
frompsycopg2.pool
- Re-added the database prompt, since now we'll only need to create the connections in one place, and therefore we'll only ask this once.
- Created the pool using
pool = SimpleConnectionPool()
.
# Arguments to SimpleConnectionPool
minconn
is the minimum number of connections. These are the connections that will be created immediately when the pool is created.maxconn
is the maximum number of connections. If we request a connection from the pool but we have ran out, a new connection will be created unless we already havemaxconn
connections. If that's the case, an error will be raised.**kwargs
get passed topsycopg2.connect
, soSimpleConnectionPool
can actually accept any keyword arguments thatpsycopg2.connect
would accept in order to connect to the database. Here we're passingdsn=
which is the database URI.
# Using the connection pool
Using the pool is very easy. Our model classes will call pool.getconn()
and pool.putconn()
, like so:
def save(self):
connection = pool.getconn()
new_poll_id = database.create_poll(connection, self.title, self.owner)
pool.putconn(connection)
self.id = new_poll_id
Note that pool.getconn()
returns a connection. We assign that to a variable, and then pass it to pool.putconn(connection)
at the end.
We should do this to all model class methods, so that they're no longer calling create_connection()
.
Remember to change the imports as well:
-from connections import create_connection
+from connection_pool import pool
# Changes to app.py
In app.py
we're creating our tables, so we need to make a small change there too to use the connection pool:
-connection = create_connection()
+connection = pool.getconn()
database.create_tables(connection)
+pool.putconn(connection)
Enjoyed this article?
You'll love the complete video course!
- Complete video lessons for each topic
- Get the most out of your learning
- Master Advanced PostgreSQL
- Get one-on-one help from a real person