[Django] #32414: Syntax Error when combining __in and F() in filter

10 views
Skip to first unread message

Django

unread,
Feb 3, 2021, 11:47:41 PM2/3/21
to django-...@googlegroups.com
#32414: Syntax Error when combining __in and F() in filter
-------------------------------------+-------------------------------------
Reporter: dfrank8 | Owner: nobody
Type: | Status: new
Uncategorized |
Component: Database | Version: 3.1
layer (models, ORM) |
Severity: Normal | Keywords: F()
Triage Stage: | Has patch: 0
Unreviewed |
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-------------------------------------+-------------------------------------
Similar to https://code.djangoproject.com/ticket/32151

I have a simple Google Calendar Events application. Profiles generate
calendar tokens with GSuite Oauth (not shown) that are used to make
CalendarEvents in my database (postgres:9.6). CalendarEvents queried via a
particular CalendarToken have the token's profile on the model. See
oversimplified example below:

{{{
class Profile(models.Model):
name = models.CharField(max_length=32)

class CalendarEvent(models.Model):
profile = models.ForeignKey(Profile, on_delete=models.CASCADE)
attendees = models.ManyToManyField(Profile, on_delete=models.CASCADE)
}}}

I'm trying to annotate whether a profile is "attending" the event, by
checking if the profile is in the attendees ManyToMany:
{{{
CalendarEvent.objects.annotate(
is_attending=Case(
When(
profile__in=F('attendees'),
then=Value(True)
),
default=Value(False),
output_field=models.BooleanField()
)
)
}}}

Generates an invalid syntax error (replacing db name with'' {APP}''):
{{{
ProgrammingError: syntax error at or near
""{APP}_calendarevent_attendees""
LINE 1: ...CASE WHEN ("{APP}_calendarevent"."profile_id" IN "{APP}_ca...
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/32414>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Feb 3, 2021, 11:48:48 PM2/3/21
to django-...@googlegroups.com
#32414: Syntax Error when combining __in and F() in filter
-------------------------------------+-------------------------------------
Reporter: dfrank8 | Owner: nobody
Type: Uncategorized | Status: new
Component: Database layer | Version: 3.1
(models, ORM) |
Severity: Normal | Resolution:
Keywords: F() | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Description changed by dfrank8:

Old description:

New description:

Similar to https://code.djangoproject.com/ticket/32151

I have a simple Google Calendar Events application. Profiles generate
calendar tokens with GSuite Oauth (not shown) that are used to make
CalendarEvents in my database (postgres:9.6). CalendarEvents queried via a
particular CalendarToken have the token's profile on the model. See
oversimplified example below:

{{{
class Profile(models.Model):
name = models.CharField(max_length=32)

class CalendarEvent(models.Model):
profile = models.ForeignKey(Profile, on_delete=models.CASCADE)

attendees = models.ManyToManyField(Profile, blank=True,
related_name="attending_calendar_events")
}}}

I'm trying to annotate whether a profile is "attending" the event, by
checking if the profile is in the attendees ManyToMany:
{{{
CalendarEvent.objects.annotate(
is_attending=Case(
When(
profile__in=F('attendees'),
then=Value(True)
),
default=Value(False),
output_field=models.BooleanField()
)
)
}}}

Generates an invalid syntax error (replacing db name with'' {APP}''):
{{{
ProgrammingError: syntax error at or near
""{APP}_calendarevent_attendees""
LINE 1: ...CASE WHEN ("{APP}_calendarevent"."profile_id" IN "{APP}_ca...
}}}

--

--
Ticket URL: <https://code.djangoproject.com/ticket/32414#comment:1>

Django

unread,
Feb 4, 2021, 12:05:21 AM2/4/21
to django-...@googlegroups.com
#32414: Syntax Error when combining __in and F() in filter
-------------------------------------+-------------------------------------
Reporter: dfrank8 | Owner: nobody
Type: Uncategorized | Status: new
Component: Database layer | Version: 3.1
(models, ORM) |
Severity: Normal | Resolution:
Keywords: F() | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Simon Charette):

Looks like you either want `attendees=F('profile')` or
`profile__in=CalendarEvent.attendees.through.objects.filter(calendarevent=OuterRef('pk'))`.

I guess we could raise a Python level error or adjust
`RelatedIn.get_prep_lookup` special case `F` referring to many-to-many as
well.

--
Ticket URL: <https://code.djangoproject.com/ticket/32414#comment:2>

Django

unread,
Feb 4, 2021, 12:41:01 AM2/4/21
to django-...@googlegroups.com
#32414: Syntax Error when combining __in and F() in filter
-------------------------------------+-------------------------------------
Reporter: Douglas Franklin | Owner: nobody

Type: Uncategorized | Status: new
Component: Database layer | Version: 3.1
(models, ORM) |
Severity: Normal | Resolution:
Keywords: F() | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Douglas Franklin):

The latter worked perfectly. Really interesting. Thank you! I agree
though, seems like a practical use-case to have the special case when
`get_prep_lookup` `F` refers to a many-to-many.

The use of the through-table subquery is working for me, so it seems like
an easy enough workaround.

Replying to [comment:2 Simon Charette]:


> Looks like you either want `attendees=F('profile')` or

`profile__in=CalendarEvent.attendees.through.objects.filter(calendarevent=OuterRef('pk')).values('profile')`.


>
> I guess we could raise a Python level error or adjust
`RelatedIn.get_prep_lookup` special case `F` referring to many-to-many as
well.

--
Ticket URL: <https://code.djangoproject.com/ticket/32414#comment:3>

Django

unread,
Feb 4, 2021, 9:54:17 AM2/4/21
to django-...@googlegroups.com
#32414: Syntax Error when combining __in and F() in filter
-------------------------------------+-------------------------------------
Reporter: Douglas Franklin | Owner: nobody
Type: Uncategorized | Status: closed

Component: Database layer | Version: 3.1
(models, ORM) |
Severity: Normal | Resolution: duplicate

Keywords: F() | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Mariusz Felisiak):

* status: new => closed
* resolution: => duplicate


Comment:

Duplicate of #31135. Please feel-free to add a comment to the original
ticket.

--
Ticket URL: <https://code.djangoproject.com/ticket/32414#comment:4>

Reply all
Reply to author
Forward
0 new messages