sql >> Databáze >  >> RDS >> PostgreSQL

SQLAlchemy Text Shoda dat uvnitř pole JSON s UTF-8

Problém spočívá v cast(Unicode) json Postgresql sloupec. Jednoduše přenese json na typ textu, který je základem Unicode SQLAlchemy , v případě Postgresql VARCHAR . Jinými slovy, vytváří řetězcovou reprezentaci JSON namísto extrahování textového obsahu. Pokud váš vstup obsahoval kódové body unicode s escapováním, jsou na výstupu stejně jako v tomto případě. Byl proveden jednoduchý Test model s json sloupec data :

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."'

Mělo by být zřejmé, proč shoda s neuvedenými znaky unicode selže. Správným způsobem, jak extrahovat textový obsah, aniž by došlo k escapování unicode, je použít astext , která používá ->> operátor v Postgresql:

In [13]: session.query(Test.data['summary'].astext).scalar()
Out[13]: 'Tämä on summary.'

Citace dokumentace funkcí JSON a operátorů:

Takže ve vašem případě:

Message.query.\
    filter(Message.content['summary'].astext.match(term))

Upozorňujeme, že to platí pouze pro json zadejte, nikoli jsonb , protože json typ nepřevádí unicode escape na vstupu. jsonb na druhou stranu převede všechny unicode escape na ekvivalentní ASCII nebo UTF-8 znaky pro uložení . Pokud náš Test model obsahoval druhý sloupec data2 jsonb , s přesně stejným vstupem, pak by výsledek byl:

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"')

Přesto byste měli použít astext , pokud chcete text místo řetězcové reprezentace JSON.




  1. Co se děje s řetězcem odpovídajícím celočíselnému poli MySQL?

  2. Jak vložit cizí klíč do modelu sequelize

  3. Ekvivalent MYSQL group_concat v Sybase ASE?

  4. Smyčka přes vkládací dotaz v PHP