Проблемът е в cast(Unicode)
на Postgresql json
колона. Той просто предава json
към типа текст, лежащ в основата на Unicode
на SQLAlchemy , в случай на Postgresql VARCHAR
. С други думи, той създава низово представяне на JSON, вместо да извлича текстовото съдържание. Ако вашият вход съдържа екранирани уникод кодови точки, те се извеждат както е в този случай. Даден е прост 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 ще се провали. Правилният начин за извличане на текстовото съдържание, премахване на екранирания уникод, е да се използва 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
от друга страна преобразува всички уникод екрани в еквивалентен ASCII или UTF-8 знаци за съхранение
. Ако нашият Test
моделът съдържаше втора колона 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.