JSONFieldの項目を別テーブルのキーとマッチさせてSubqueryで項目を取りたかったのです。
結果としては
ename = Subquery(Event.objects.filter(eid=RawSQL("url_kwargs->>'eid'", [])).values('ename')[:1]),
として動いているんですが。
見ての通り、RawSQLを使うことになりました。
① 素直に考えると
ename=Subquery(Event.objects.filter(eid=OuterRef('url_kwargs__eid')).values('ename')[:1]),
でいけそうなのですが、
operator does not exist: character varying = jsonb
と型が一致しないとエラーになりました。
② 型エラーならばと
ename=Subquery(Event.objects.filter(eid=Cast(OuterRef('arguments__eid'),CharField())).values('ename')[:1])
とCastするとエラーは出なくなりましたがマッチするレコードがある場合でもenameが取得されてきません。
色々確認すると、JSONFieldをキャストするとダブルクオート(")で括られた文字列になるせいでマッチしなくなってました。
私はここで諦めて、RawSQLで実装することにしました。
もしRawSQLでなく実装する方法が分かる方がおられましたらご教示いただけると幸いです。
今回の事象を確認した各種バージョン
Python 3.12.3
django 5.1.5
PostgreSQL 16.6 (Ubuntu 16.6-0ubuntu0.24.04.1)
余談
ちなみに、AIに上記①でエラーになる旨の対処方法を聞くと②が提案されて、
②の状況を伝えて対処方法を聞くと①の提案が返ってきました。
次善策としてRawSQLでの方法も提案されますが。
ちゃんと有償の優秀なAIに聞けばより良い返答があるのかも気になるところです。