Opened 6 years ago
Closed 6 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 thejsonb
type. From Django's perspectivecontext__key
is aJSONField
and from PostgreSQL it isjsonb
.This is the case because it's not possible to determine whether
url_key
should be converted tojsonb
or"context" -> 'key'
totext
so 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
str
onOuterRef
won'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 aCast
function orKeyTextTransform
annotations 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.