問題はcast(Unicode)
にあります Postgresqlのjson
桁。 json
をキャストするだけです SQLAlchemyのUnicode
の基礎となるテキストタイプに 、Postgresql VARCHAR
の場合 。つまり、テキストコンテンツを抽出する代わりに、JSONの文字列表現を生成します。入力にエスケープされたUnicodeコードポイントが含まれている場合、この場合はそのまま出力されます。与えられた単純なTest
json
を使用したモデル 列データ :
In [7]: t = Test(data={'summary': 'Tämä on summary.'})
In [8]: session.add(t)
In [9]: session.commit()
In [11]: session.query(Test.data['summary'].cast(Unicode)).scalar()
Out[11]: '"T\\u00e4m\\u00e4 on summary."'
エスケープされていないUnicode文字との一致が失敗する理由は明らかです。エスケープされたUnicodeをエスケープせずにテキストコンテンツを抽出する正しい方法は、 astext
、 ->>
を使用します オペレーター
Postgresqlの場合:
In [13]: session.query(Test.data['summary'].astext).scalar()
Out[13]: 'Tämä on summary.'
JSON関数と演算子のドキュメントの引用:
だからあなたの場合:
Message.query.\
filter(Message.content['summary'].astext.match(term))
これはjson
にのみ適用されることに注意してください jsonb
ではなくタイプ 、json
typeは、入力時にUnicodeエスケープを変換しません。 jsonb
一方、すべてのUnicodeエスケープを同等のASCIIまたはUTF-8に変換しますストレージ用の文字
。 Test
の場合 モデルには2番目の列data2 jsonb
が含まれていました 、まったく同じ入力の場合、結果は次のようになります。
In [11]: session.query(Test.data['summary'].cast(Unicode),
...: Test.data2['summary'].cast(Unicode)).first()
Out[11]: ('"T\\u00e4m\\u00e4 on summary."', '"Tämä on summary"')
それでも、astext
を使用する必要があります 、JSONの文字列表現の代わりにテキストが必要な場合。