sql >> データベース >  >> RDS >> PostgreSQL

辞書を使用してパラメーターをPythonのpostgresqlステートメントに渡す

    ドキュメント で説明されているパラメータ化されたクエリを使用してください

    あなたはすでに口述を持っているので、あなたは次のことができます:

    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)
    

    私は、それが古いdictで機能するかどうかをテストしていませんが、そうすべきだと思います。そうでない場合は、パラメータマッピングとして渡す前に、順序付けられたdictを通常のdictにすることができます。

    編集 後でパラメータをOrderedDictにする必要がない限り、通常のdictを使用してください。私が見る限り、list(query_params.values())[0]の値の順序を保持するためにOrderedDictを選択しただけです。 。

    編集2 テーブル名とフィールド名は、バインディングを使用して渡すことはできません。 AntoineDusséauxはこの回答 で指摘しました そのpsycopg2は、バージョン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)
    

    table_nameを削除する必要がある場合があります あなたの口述から、私はpsycopg2がパラメータdictの追加項目にどのように反応するかわかりません、そして私は今それをテストすることができません。

    これは依然としてSQLインジェクションのリスクをもたらすため、絶対に必要な場合を除いて回避する必要があることを指摘しておく必要があります。通常、テーブル名とフィールド名はクエリ文字列のかなり固定された部分です。

    これは、関連する sqlのドキュメントです。 モジュール



    1. 不確定な数の列でUNPIVOT

    2. PythonでSSLを介してリモートPostgreSQLデータベースに接続する方法

    3. プライマリには、テーブルのパーティション分割場所エラーのすべての列が含まれている必要がありますか?

    4. 投稿配列をコンマ区切りの列値で検索します