Search code examples
pythondjangopostgresqlsqlalchemyconnection-pool

Database connection object is not callable exception thrown with Python Django SQL Alchemy database pooling. Why?


What I'm trying to achieve

Create a database connection pool in Django. The connection pool is connected to a PostgreSQL database by using SQLAlchemy's connection pooling with django-postgrespool2.

Thrown exception

'psycopg2.extensions.connection' object is not callable is thrown when running the following line of code poolConnection = dbPool.connect(). Printing the dbPool object and type displays <sqlalchemy.pool.impl.QueuePool object at 0x00000171832A72B0> <class 'sqlalchemy.pool.impl.QueuePool'>

Code

Database helper class which creates the connection to the PostgreSQL database and creates the connection pool:

import psycopg2
from sqlalchemy import pool
import traceback

dbPool = None

class DbPoolHelper:

    def ensurePoolCreated(self):
        global dbPool
        if dbPool != None:
            return
            
        self.createPool()

    def dbConnect(self):
        dbConnection = psycopg2.connect(user="...", password="...", dbname="...", host="...",port="...")
        return dbConnection

    def createPool(self):
        dbConnection = self.dbConnect()
        global dbPool
        dbPool = pool.QueuePool(dbConnection, max_overflow=10, pool_size=5)

    def execute(self, sql, sqlParams):
        try:
            global dbPool
            self.ensurePoolCreated()
            poolConnection = dbPool.connect()
            cursor = poolConnection.cursor()
            cursor.execute(sql, sqlParams)
            poolConnection.commit()
            result = cursor.fetchall()
            cursor.close()
            poolConnection.close()
            return result
        except Exception as e:
            print(e)
            return e

The code using the DbPoolHelper to fetch some data by using the execute method and giving some sql and sql params as arguments:

def poolTest():
    sql = "SELECT * FROM sysproductcontainers;"
    sqlParams = ()
    db = DbPoolHelper()
    result = db.execute(sql, sqlParams)

Question

Why does the code throw 'psycopg2.extensions.connection' object is not callable?

Keep in mind that I am pretty new to Python and Django. So I might be missing something obvious to some Python and/or Django developers.

Thanks!


Solution

  • According to the QueuePool docs the first argument should be 'a callable function that returns a DB-API connection object'.

    You've passed the result of the called function to the QueuePool object as the first argument instead of the function itself. Remove the parenthesis to solve the issue:

    def createPool(self):
        dbConnection = self.dbConnect
        global dbPool
        dbPool = pool.QueuePool(dbConnection, max_overflow=10, pool_size=5)