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

SQLAlchemyテキストJSONフィールド内のデータとUTF-8のマッチング

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




    1. データベースに値を保存する際の問題

    2. @Versionを休止すると、データベースの外部キー制約が失敗します

    3. 1つの値について複数の列をチェックする

    4. mySQLで検索を制限して文字列を置き換える方法