問題は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の文字列表現の代わりにテキストが必要な場合。