SqlAlchemy + cx_Oracleで生SQLのIN句のバインド変数を使用する方法

この記事は公開から2年以上経過しています。

SqlAlchemy(1.4) + cx_Oracle(8.3)の生SQLで

item_names = ['A', 'B', 'C']
rows = engine.execute(
        'SELECT * FROM TEST_TBL WHERE ITEM_NAME IN(:item_names)', item_names).fetchall()

のような表記でIN句のバインド変数を使用すると

Exception has occurred: DatabaseError
(cx_Oracle.DatabaseError) ORA-01036: illegal variable name/number
[SQL: SELECT * FROM TEST_TBL WHERE ITEM_NAME IN(:item_names]
[parameters: [‘A’, ‘B’, ‘C’]]
(Background on this error at: https://sqlalche.me/e/14/4xp6)

といったエラーが発生する。


原因

cx_OracleのSQLのIN句はバインド変数1個につき1個の値しかバインドできないため。


対応

バインド変数と値を1対1でバインドする。

bind_names = [f':{i}' for i, o in enumerate(item_names)]
rows = engine.execute(
    'SELECT * FROM TEST_TBL WHERE ITEM_NAME IN(%s)' % (','.join(bind_names)), item_names).fetchall()


参考ウェブサイトなど

  • cx_Oracle
    Binding Multiple Values to a SQL WHERE IN Clause

以上です。

シェアする

  • このエントリーをはてなブックマークに追加

フォローする