Opened 7 years ago
Closed 7 years ago
#29731 closed Bug (invalid)
Type conversion should be possible with OuterRef
| Reported by: | Étienne Beaulé | Owned by: | nobody |
|---|---|---|---|
| Component: | Database layer (models, ORM) | Version: | 2.1 |
| Severity: | Normal | Keywords: | postgresql, sql, json, outerref |
| Cc: | Triage Stage: | Unreviewed | |
| Has patch: | no | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
With the query:
subquery = SentMessageRecord.objects.filter(tournament=self.tournament, email=OuterRef('email'), context__key=OuterRef('url_key'), event=SentMessageRecord.EVENT_TYPE_URL)
people = self.tournament.participants.filter(url_key__isnull=False, email__isnull=False).exclude(email__exact="").annotate(already_sent=Exists(subquery)).filter(already_sent=already_sent)
where url_key is a CharField and context is a JsonField (using Postgres), the __key is a string that corresponds to url_key. However, I get the error:
django.db.utils.ProgrammingError: operator does not exist: jsonb = character varying
LINE 1: ...tmessagerecord" U0 WHERE ((U0."context" -> 'key') = ("partic...
^
HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts.
Wrapping the OuterRef with str() prevents the error, but seems to be ineffective.
Note:
See TracTickets
for help on using tickets.
Hey tienne-B,
Unfortunately it's not possible for Django, nor PostgreSQL, to automatically determine that
context__key("context" -> 'key') is a string by the untyped and dynamic nature of thejsonbtype. From Django's perspectivecontext__keyis aJSONFieldand from PostgreSQL it isjsonb.This is the case because it's not possible to determine whether
url_keyshould be converted tojsonbor"context" -> 'key'totextso it is necessary to provide an explicit cast as PostgreSQL suggests. I'd say that here both Django and PostgreSQL refuse the temptation to guess.Unfortunately calling
stronOuterRefwon't work as the Django ORM doesn't implement this kind of high level magic like ORM such as Peewee provide. In these cases you'll have to rely on either aCastfunction orKeyTextTransformannotations instead.For example using
Cast.Given this isn't a defect with Django I'd say this would qualify as a usage question and would better be addressed through support channels. Without deterring you from reporting legitimate bugs it's always better to confirm whether or not an issue can be resolved on support channels before escalating to this tracker which is used to track defect and feature requests.