Skip to content

query/mogrify broken when named parameters are used more than once #378

@wolph

Description

@wolph

The issue is with the dump function that automatically converts all parameters into tuples but doesn't take into consideration that some parameters might be used more than once.

def dump(self, vars: Optional[Params]) -> None:
"""
Process a new set of variables on the query processed by `convert()`.
This method updates `params` and `types`.
"""
if vars is not None:
params = _validate_and_reorder_params(self._parts, vars, self._order)
self.params = tuple(
self._tx.as_literal(p) if p is not None else b"NULL" for p in params
)
self.query = self.template % self.params
else:
self.params = None

The traceback:

Traceback (most recent call last):
  File "psycopg/client_cursor.py", line 40, in mogrify
    pgq = self._convert_query(query, params)
  File "psycopg/client_cursor.py", line 79, in _convert_query
    pgq.convert(query, params)
  File "psycopg/_queries.py", line 129, in convert
    self.dump(vars)
  File "psycopg/_queries.py", line 142, in dump
    self.query = self.template % self.params
TypeError: not enough arguments for format string

To reproduce:

query = '''
SELECT *
FROM some_table
WHERE some_column = %(some_value)s
AND some_other_column = %(some_value)s
'''
params = dict(some_value=1)

with psycopg.connect() as connection:
    cursor = psycopg.ClientCursor(connection)
    cursor.mogrify(query, params)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions