sql >> Base de Datos >  >> RDS >> PostgreSQL

Usando un diccionario para pasar parámetros a la declaración postgresql en python

Utilice una consulta parametrizada como se describe en los documentos

Como ya tiene un dict, podría hacer:

sql_data_sample = """select * from %(table_name)s
           where dt = %(date_from)s
           and target in ('ACTIVE')
           ----------------------------------------------------
           union all
           ----------------------------------------------------
           (select * from %(table_name)s
           where dt = %(date_to)s
           and target in (%(class_target)s));"""

cur.execute(sql_data_sample, query_params)

No he probado si funciona con un dictado ordenado, pero creo que debería. De lo contrario, puede hacer que su dictado ordenado sea un dictado regular antes de pasarlo como asignación de parámetros.

EDITAR A menos que necesite que sus parámetros sean un OrderedDict más adelante, use un dictado regular. Por lo que puedo ver, solo optó por un OrderedDict para preservar el orden de valores para la list(query_params.values())[0] .

EDITAR2 Los nombres de tablas y de campos no se pueden pasar mediante enlaces. Antoine Dusséaux señaló en esta respuesta que psycopg2 ofrece una forma más o menos segura de hacerlo desde la versión 2.7.

from psycopg2 import sql

sql_data_sample = """select * from {0}
           where dt = %(date_from)s
           and target in ('ACTIVE')
           ----------------------------------------------------
           union all
           ----------------------------------------------------
           (select * from {0}
           where dt = %(date_to)s
           and target in (%(class_target)s));"""

cur.execute(sql.SQL(sql_data_sample)
                .format(sql.Identifier(query_params['table_name'])), 
            query_params)

Es posible que deba eliminar table_name de su dict, no estoy seguro de cómo reacciona psycopg2 en elementos adicionales en el dict de parámetros y no puedo probarlo en este momento.

Debe señalarse que esto aún presenta el riesgo de inyección SQL y debe evitarse a menos que sea absolutamente necesario. Normalmente, los nombres de tablas y campos son una parte bastante fija de una cadena de consulta.

Aquí está la documentación relevante para sql módulo .