sql >> Database teknologi >  >> RDS >> PostgreSQL

SQLAlchemy Text Matching-data inde i JSON-feltet med UTF-8

Problemet ligger i cast(Unicode) af en Postgresql json kolonne. Det CAST simpelthen json til teksttypen, der ligger til grund for SQLAlchemys Unicode , i tilfælde af Postgresql VARCHAR . Med andre ord producerer den en strengrepræsentation af JSON i stedet for at udtrække tekstindholdet. Hvis dit input indeholdt undslupne unicode-kodepunkter, udsendes de som i dette tilfælde. Givet en simpel Test model med en json kolonne 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."'

Det burde være tydeligt, hvorfor et match med unescaped unicode-tegn vil mislykkes. Den korrekte måde at udtrække tekstindholdet på, uden at undslippe escaped unicode, er at bruge astext , som bruger ->> operatør i Postgresql:

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

Med henvisning til JSON-funktioner og operatørdokumentation:

Så i dit tilfælde:

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

Bemærk, at dette kun gælder for json type, ikke jsonb , fordi json type konverterer ikke unicode-escapes ved input. jsonb på den anden side konverterer alle unicode-escapes til tilsvarende ASCII eller UTF-8 tegn til opbevaring . Hvis vores Test modellen indeholdt en anden kolonne data2 jsonb , med nøjagtig samme input, så ville resultatet være:

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

Alligevel bør du bruge astext , hvis du ønsker tekst i stedet for en strengrepræsentation af JSON.




  1. MySQL vælg med underforespørgsel og LIMIT

  2. Brug af kommandoen LOAD DATA INFILE i en lagret procedure

  3. PostgreSQL - Korreleret underforespørgsel mislykkedes?

  4. Skal trimme blank plads i oracle