Masalahnya terletak pada cast(Unicode)
dari json
Postgresql kolom. Itu hanya CAST json
ke jenis teks yang mendasari Unicode
SQLAlchemy , dalam kasus Postgresql VARCHAR
. Dengan kata lain itu menghasilkan representasi string JSON alih-alih mengekstraksi konten teks. Jika input Anda berisi codepoint unicode yang lolos, mereka akan keluar seperti dalam kasus ini. Diberikan Test
sederhana model dengan json
kolom 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."'
Harus jelas mengapa kecocokan dengan karakter unicode yang tidak lolos akan gagal. Cara yang benar untuk mengekstrak konten teks, melepaskan unicode yang lolos, adalah dengan menggunakan astext
, yang menggunakan ->>
operator
di Postgresql:
In [13]: session.query(Test.data['summary'].astext).scalar()
Out[13]: 'Tämä on summary.'
Mengutip fungsi JSON dan dokumentasi operator:
Jadi dalam kasus Anda:
Message.query.\
filter(Message.content['summary'].astext.match(term))
Perhatikan bahwa ini hanya berlaku untuk json
ketik, bukan jsonb
, karena json
type tidak mengonversi unicode lolos pada input. jsonb
di sisi lain mengonversi semua unicode lolos ke ASCII atau UTF-8 yang setara karakter untuk penyimpanan
. Jika Test
kami model berisi kolom kedua data2 jsonb
, dengan input yang sama persis, maka hasilnya adalah:
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"')
Namun, Anda harus menggunakan astext
, jika Anda menginginkan teks alih-alih representasi string dari JSON.