2017-09-03 6 views
0

整数とJSONBデータを受け取る関数を実行する必要があります。通常のコンソールで 、私はこのようにそれを実行します:SQLAlchemyの 'execute'を使用してJSONBを挿入する方法はありますか?

select my_func(0, '{"foo": "bar"}'::jsonb)

これは、私はそれがSQLAlchemyのに働くだろうと想定する方法である:

params = {'p1': 0, 'p2': JSONB('{"foo": "bar"}'))} 
result = db.engine.execute(text('select my_func(:p1, :p2)'), params) 

しかし、それはしません。挿入しようとしているJSONBであることをSQLAlchemyに理解させるにはどうすればいいですか?

答えて

3

JSONBは、値を扱うのではなく、列の型を定義するためのものです。あなたはそれを自分でシリアル化せずに辞書を渡す必要があり

params = { 'p1': 0, 'p2': { "foo": "bar" } } 
result = db.engine.execute(
    text('select my_func(:p1, :p2)').bindparams(
     bindparam('p2', type_=JSONB)), 
    params) 

注:原文のSQLおよび必要なタイプを使用する場合は、特別な治療PythonやSQL側は追加の型情報を提供するために、TextClause.bindparams()メソッドを使用します。 bindparams()を使用せずにSQLAlchemyの型情報を提供すると、バインド値はテキストSQLを使用しているときとほとんど同じようにDB-APIカーソルに渡されます。その光の中で、これも動作するはずです:

params = {'p1': 0, 'p2': '{"foo": "bar"}'} 
result = db.engine.execute(
    text('select my_func(:p1, cast(:p2 as jsonb))'), 
    params) 

DB-APIドライバーは、文字列のバインド値を見て、いつものようにすることを処理します。 SQLでの明示的なキャストも冗長になる可能性があります。

+0

私が探していたもの!私はこの質問を投稿した直後にSQLの文字列にキャストすることを実現し、それを "回避策"として使用しました。しかし、bindparamsはそれを行うための公式の方法のように見えるので、一緒に行くでしょう! – fgblomqvist

関連する問題