PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Usando um dicionário para passar parâmetros para a instrução postgresql em python


Use uma consulta parametrizada conforme descrito nos documentos

Como você já tem um dict, você pode fazer:
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)

Eu não testei se funciona com um dict odered, mas acho que deveria. Caso contrário, você pode tornar seu dict ordenado um dict regular antes de passá-lo como mapeamento de parâmetros.

EDITAR A menos que você precise que seus parâmetros sejam um OrderedDict mais tarde, use um dict regular. Até onde posso ver, você optou apenas por um OrderedDict para preservar a ordem de valor para o list(query_params.values())[0] .

EDIT2 Nomes de tabela e nomes de campo não podem ser passados ​​usando associações. Antoine Dusséaux apontou esta resposta que o psycopg2 oferece uma maneira mais ou menos segura de fazer isso desde a versão 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)

Você pode ter que remover o table_name do seu dict, não tenho certeza de como o psycopg2 reage em itens adicionais no dict de parâmetros e não posso testá-lo agora.

Deve-se ressaltar que isso ainda apresenta o risco de injeção de SQL e deve ser evitado, a menos que seja absolutamente necessário. Normalmente, os nomes de tabelas e campos são uma parte fixa de uma string de consulta.

Aqui está a documentação relevante para o sql módulo .