psycopg/psycopg2 · error · TypeError

you can't specify both 'database' and 'dbname' arguments

Error message

you can't specify both 'database' and 'dbname' arguments

What it means

Raised by make_dsn() (lib/extensions.py:150-152) when both 'database' and 'dbname' are present in the keyword arguments. These are aliases for the same PostgreSQL connection parameter (libpq uses 'dbname'); psycopg2 accepts 'database' for familiarity but forbids specifying both to avoid ambiguity about which value wins.

Source

Thrown at lib/extensions.py:151

    def getquoted(self, _null=b"NULL"):
        return _null


def make_dsn(dsn=None, **kwargs):
    """Convert a set of keywords into a connection strings."""
    if dsn is None and not kwargs:
        return ''

    # If no kwarg is specified don't mung the dsn, but verify it
    if not kwargs:
        parse_dsn(dsn)
        return dsn

    # Override the dsn with the parameters
    if 'database' in kwargs:
        if 'dbname' in kwargs:
            raise TypeError(
                "you can't specify both 'database' and 'dbname' arguments")
        kwargs['dbname'] = kwargs.pop('database')

    # Drop the None arguments
    kwargs = {k: v for (k, v) in kwargs.items() if v is not None}

    if dsn is not None:
        tmp = parse_dsn(dsn)
        tmp.update(kwargs)
        kwargs = tmp

    dsn = " ".join(["{}={}".format(k, _param_escape(str(v)))
        for (k, v) in kwargs.items()])

    # verify that the returned dsn is valid
    parse_dsn(dsn)

    return dsn

View on GitHub (pinned to 3a6d9d6ddc)

Solutions

  1. Standardize on a single key: use 'dbname' everywhere (libpq native) or 'database' everywhere.
  2. When merging configs, drop one alias before calling connect/make_dsn: kwargs.pop('database', None).
  3. If using make_dsn(dsn, **kwargs), ensure the DSN string and kwargs don't each contribute a different alias.

Example fix

// before
conn = psycopg2.connect(host=h, dbname='prod', database='prod')
// after
conn = psycopg2.connect(host=h, dbname='prod')
Defensive patterns

Strategy: validation

Validate before calling

if 'database' in kwargs and 'dbname' in kwargs:
    raise TypeError('specify only one of database/dbname')
if 'database' in kwargs:
    kwargs['dbname'] = kwargs.pop('database')

Type guard

def has_duplicate_db_key(kwargs: dict) -> bool:
    return 'database' in kwargs and 'dbname' in kwargs

Try / catch

try:
    conn = psycopg2.connect(**kwargs)
except TypeError as e:
    if 'database' in str(e) and 'dbname' in str(e):
        kwargs.pop('database', None)
        conn = psycopg2.connect(**kwargs)
    else: raise

Prevention

When it happens

Trigger: Calling psycopg2.connect() or make_dsn() with both database=... and dbname=... in the same call, e.g. connect(dbname='x', database='y'), or passing a kwargs dict that merges two config sources each using a different alias.

Common situations: Merging a base DSN/kwargs (using 'dbname') with overrides (using 'database') from environment variables or a config file. Common when a framework uses 'database' (SQLAlchemy/ Django style) while the ops layer uses 'dbname' (libpq style).

Related errors


AI-assisted analysis of psycopg/psycopg2@3a6d9d6ddc (2026-08-04). Data as JSON: /data/errors/2463f02dd29c609f.json. Report an issue: GitHub.