Opened 3 years ago

Closed 3 years ago

#32318 closed Bug (duplicate)

Collect on annotated values causes error

Reported by: Adrian Martinez Rodriguez Owned by: nobody
Component: GIS Version: 3.1
Severity: Normal Keywords: Collect, annotate, aggregate
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

django.contrib.gis.db.models.Collect does not work on annotated values

Steps to reproduce:

# create models
class SampleItem(models.Model):
    name = models.CharField(max_length=250)


class SampleLocation(models.Model):
    point = PointField()
    item = models.OneToOneField(SampleItem, on_delete=models.CASCADE)


def run_this():
    # import models
    from django.db.models.expressions import Subquery
    from django.contrib.gis.geos.point import Point
    from django.contrib.gis.db.models import Collect
    from django.db.models import OuterRef
    item = SampleItem.objects.create(name="Sample Item")
    SampleLocation.objects.create(item=item, point=Point(50, 50))
    
    sub = Subquery(SampleLocation.objects.filter(item=OuterRef("pk")).values("point")[:1])
    locations = SampleItem.objects.annotate(location=sub).aggregate(locations=Collect("location"))  # Throws error

Last line will trhow the following error:

/usr/local/lib/python3.6/site-packages/django/db/models/query.py in aggregate(self, *args, **kwargs)
    396             if not query.annotations[alias].contains_aggregate:
    397                 raise TypeError("%s is not an aggregate expression" % alias)
--> 398         return query.get_aggregation(self.db, kwargs)
    399
    400     def count(self):

/usr/local/lib/python3.6/site-packages/django/db/models/sql/query.py in get_aggregation(self, using, added_aggregate_names)
    503
    504         converters = compiler.get_converters(outer_query.annotation_select.values())
--> 505         result = next(compiler.apply_converters((result,), converters))
    506
    507         return dict(zip(outer_query.annotation_select, result))

/usr/local/lib/python3.6/site-packages/django/db/models/sql/compiler.py in apply_converters(self, rows, converters)
   1098                 value = row[pos]
   1099                 for converter in convs:
-> 1100                     value = converter(value, expression, connection)
   1101                 row[pos] = value
   1102             yield row

/usr/local/lib/python3.6/site-packages/django/contrib/gis/db/backends/postgis/operations.py in converter(value, expression, connection)
    385
    386         def converter(value, expression, connection):
--> 387             return None if value is None else GEOSGeometryBase(read(value), geom_class)
    388         return converter
    389

/usr/local/lib/python3.6/site-packages/django/contrib/gis/geos/prototypes/io.py in read(self, wkb)
    151             return wkb_reader_read(self.ptr, wkb_s, len(wkb_s))
    152         elif isinstance(wkb, (bytes, str)):
--> 153             return wkb_reader_read_hex(self.ptr, wkb, len(wkb))
    154         else:
    155             raise TypeError

/usr/local/lib/python3.6/site-packages/django/contrib/gis/geos/libgeos.py in __call__(self, *args)
    150
    151     def __call__(self, *args):
--> 152         return self.func(*args)
    153
    154     @cached_property

/usr/local/lib/python3.6/site-packages/django/contrib/gis/geos/prototypes/threadsafe.py in __call__(self, *args)
     45         # Call the threaded GEOS routine with the pointer of the context handle
     46         # as the first argument.
---> 47         return self.cfunc(self.thread_context.handle.ptr, *args)
     48
     49     def __str__(self):

ArgumentError: argument 3: <class 'TypeError'>: wrong type

Tested with Django-3.1, PostgreSQL-9.6.12, POSTGIS-2.5.2, GEOS-3.7.1, GDAL-2.4.0

Change History (1)

comment:1 by Mariusz Felisiak, 3 years ago

Resolution: duplicate
Status: newclosed

Duplicate of #31910. Fixed in Django 3.2.

Note: See TracTickets for help on using tickets.
Back to Top