TypeError: argument 2 must be a connection, cursor or None in psycopg2

123 Views Asked by At

Getting TypeError: argument 2 must be a connection, cursor or None

Below is the stack trace:

File "/root/python3/lib/python3.9/site-packages/django/core/handlers/exception.py", line 55
response = get_response(request)
File "/root/python3/lib/python3.9/site-packages/django/core/handlers/base.py", line 197, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
if not connection.get_autocommit()
File "/root/python3/lib/python3.9/site-packages/django/db/backends/base/base.py", line 416, in get_autocommit
self.ensure_connection()
File "/root/python3/lib/python3.9/site-packages/django/utils/asyncio.py", line 26
return func(*args, **kwargs)
File "/root/python3/lib/python3.9/site-packages/django/db/backends/base/base.py", line 244, in ensure_connection
self.connect()
File "/root/python3/lib/python3.9/site-packages/sentry_sdk/integrations/django/__init__.py", line 600
return real_connect(self)
File "/root/python3/lib/python3.9/site-packages/django/utils/asyncio.py", line 26
return func(*args, **kwargs)
File "/root/python3/lib/python3.9/site-packages/django/db/backends/base/base.py", line 225
self.connection = self.get_new_connection(conn_params)
File "/root/python3/lib/python3.9/site-packages/django/utils/asyncio.py", line 26
return func(*args, **kwargs)
File "/root/python3/lib/python3.9/site-packages/django/db/backends/postgresql/base.py", line 222, in get_new_connection
psycopg2.extras.register_default_jsonb
File "/root/python3/lib/python3.9/site-packages/psycopg2/_json.py", line 150, in register_default_jsonb
return register_json(conn_or_curs=conn_or_curs, globally=globally,
return register_json(conn_or_curs=conn_or_curs, globally=globally
File "/root/python3/lib/python3.9/site-packages/psycopg2/_json.py", line 120, in register_json
register_type(JSON, not globally and conn_or_curs or None)
File "/root/python3/lib/python3.9/site-packages/ddtrace/contrib/psycopg/patch.py", line 179, in _extensions_register_type
return func(obj, scope) if scope else func(obj)
TypeError: argument 2 must be a connection, cursor or None

I am using custom connection factory to make database connections like below:

def connect_with_retry(alias):
    """
    Try to establish a database connection with retry.
    :param alias: Alias of the database
    :return: psycopg2.extensions.connection object if successful, otherwise raise exception
    """
    attempt = 1
    retry_count = PGBOUNCER_RETRY_COUNT
    retry_delay = PGBOUNCER_RETRY_DELAY
    conn_string = os.getenv('DATABASE_URL')

    try:
        url_parts = urlparse.urlparse(conn_string)
        username = url_parts.username
        password = url_parts.password
        host = url_parts.hostname
        port = url_parts.port
        database_name = url_parts.path.lstrip('/')
    except Exception as ex:
        logger.error(f"Error parsing database URL: {ex}")
        # Set default values or raise an exception if appropriate
        username = password = host = port = database_name = None

    while True:
        try:
            logger.debug(
                f"Trying to make a connection with database: username - {username}, host - {host}, database_name - {database_name}"
            )
            conn = psycopg2.connect(
                dbname=database_name,
                user=username,
                password=password,
                host=host,
                port=port,
                connect_timeout=retry_delay,
            )
            logger.info(f"Connections details {conn}")
            return conn
        except (psycopg2.OperationalError, psycopg2.DatabaseError) as ex:
            attempt += 1
            if attempt > retry_count:
                logger.info(f"Database connection retry max-limit exceeded")
                raise ConnectionError("Failed to establish a database connection")
            logger.info(
                f"Connection failed, retrying in {retry_delay} seconds... (Attempt {attempt}/{retry_count})"
            )


DATABASES = {}
DATABASES["default"] = dj_database_url.config()
DATABASES["default"]["ENGINE"] = "psqlextra.backend"
DATABASES["default"]["OPTIONS"] = {
    'connection_factory': lambda alias: connect_with_retry("default")
}
POSTGRES_EXTRA_DB_BACKEND_BASE = "core.database_backend"

The issue is arising while making any API call with the above error in the stack trace while making a database connection. The concern mostly is the same code works with lower versions of django(django 3.x) and related dependencies and is failing while upgrading django version to Django4. Please help in finding the exact root cause of such behavior.

After digging deeper, found one thread which resolves same issue - https://github.com/aws/aws-xray-sdk-python/issues/243 However, the aws-xray-sdk version being used in my project is 2.11.0

Still facing the same issue. Components used are: Django==4.0.8, psycopg2==2.9.5, python==3.9.17

0

There are 0 best solutions below