File: lookups.py

package info (click to toggle)
python-django-postgres-extra 2.0.9-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,096 kB
  • sloc: python: 9,057; makefile: 17; sh: 7; sql: 1
file content (34 lines) | stat: -rw-r--r-- 1,067 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
from django.db.models import lookups
from django.db.models.fields import Field, related_lookups
from django.db.models.fields.related import ForeignObject


class InValuesLookupMixin:
    """Performs a `lhs IN VALUES ((a), (b), (c))` lookup.

    This can be significantly faster then a normal `IN (a, b, c)`. The
    latter sometimes causes the Postgres query planner do a sequential
    scan.
    """

    def as_sql(self, compiler, connection):

        if not self.rhs_is_direct_value():
            return super().as_sql(compiler, connection)

        lhs, lhs_params = self.process_lhs(compiler, connection)

        _, rhs_params = self.process_rhs(compiler, connection)
        rhs = ",".join([f"(%s)" for _ in rhs_params])  # noqa: F541

        return f"{lhs} IN (VALUES {rhs})", lhs_params + list(rhs_params)


@Field.register_lookup
class InValuesLookup(InValuesLookupMixin, lookups.In):
    lookup_name = "invalues"


@ForeignObject.register_lookup
class InValuesRelatedLookup(InValuesLookupMixin, related_lookups.RelatedIn):
    lookup_name = "invalues"