Error creating nested query with GeoDjango's spatial filters

33 views
Skip to first unread message

ejel

unread,
Jul 23, 2011, 12:14:34 AM7/23/11
to geodjango
I'm having trouble constructing nested queries using in field lookup
in GeoDjango. The following code demonstrates the problem:

inner_qs = Footprint.objects.filter(geom__bboverlaps=bounding_box)
outer_qs = Footprint.objects.filter(pk__in=inner_qs)
outer_qs.count()
# error

With the above code, the follow exception occurs:

if (len(params) == 1 and params[0] == '' and lookup_type == 'exact'
File "../python2.6/site-packages/django/contrib/gis/db/backends/
postgis/adapter.py", line 24, in __eq__
return (self.ewkb == other.ewkb) and (self.srid == other.srid)
AttributeError: 'str' object has no attribute 'ewkb'

(The complete stack trace is posted at: https://gist.github.com/1098188)

It appears that the error occurs whenever the inner query contains a
spatial filter. The following nested query works fine though:

inner_qs = Footprint.objects.filter(frequency__gt=1)
outer_qs = Footprint.objects.filter(pk__in=inner_qs)
outer_qs.count()
# ok

Any idea what causes the problem?

jpk

unread,
Nov 28, 2011, 11:02:44 PM11/28/11
to geod...@googlegroups.com
Howdy,

I'm experiencing the same problem. Were you able to resolve this?

In my case, I have a two models: Spot and Property. Spot has a
PointField called location. Property has a foreign key of the Spot it
belongs to. If I get a list of spots using a spatial filter, then get
the related properties with spot__in=spots, it blows up with "'str'
object has no attribute 'ewkb'".
Here's me reproducing the error with a full stack trace:
http://pastebin.com/XL5XNDaN

I brought it up in the irc channel: http://pastebin.com/bwZYVa6j
The conclusion was it's probably a bug in the ORM. Is that the case?
Any wisdom would be greatly appreciated.

Thanks!
john

> From: ejel <e.je...@gmail.com>
> Date: Jul 22, 11:14 pm
> Subject: Error creating nested query with GeoDjango's spatial filters
> To: geodjango
>
>
> I'm having trouble constructing nested queries using in field lookup
> in GeoDjango. The following code demonstrates the problem:
>
> inner_qs = Footprint.objects.filter(geom__bboverlaps=bounding_box)
> outer_qs = Footprint.objects.filter(pk__in=inner_qs)
> outer_qs.count()
> # error
>
> With the above code, the follow exception occurs:
>
> if (len(params) == 1 and params[0] == '' and lookup_type == 'exact'
>   File "../python2.6/site-packages/django/contrib/gis/db/backends/
> postgis/adapter.py", line 24, in __eq__

>     return (self.ewkb== other.ewkb) and (self.srid == other.srid)
> AttributeError: 'str'objecthasnoattribute'ewkb'


>
> (The complete stack trace is posted at:https://gist.github.com/
> 1098188)
>
> It appears that the error occurs whenever the inner query contains a
> spatial filter. The following nested query works fine though:
>
> inner_qs = Footprint.objects.filter(frequency__gt=1)
> outer_qs = Footprint.objects.filter(pk__in=inner_qs)
> outer_qs.count()
> # ok
>
> Any idea what causes the problem?
>

--


John P. Kiffmeyer
Email/XMPP: jo...@thekiffmeyer.org

ejel

unread,
Dec 2, 2011, 4:03:16 AM12/2/11
to geod...@googlegroups.com
I weren't able to fix the issue and resorted to raw sql instead.

> --
> You received this message because you are subscribed to the Google Groups "geodjango" group.
> To post to this group, send email to geod...@googlegroups.com.
> To unsubscribe from this group, send email to geodjango+...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/geodjango?hl=en.
>

jpk

unread,
Dec 2, 2011, 4:12:27 AM12/2/11
to geod...@googlegroups.com
Hi,

Thanks for the reply. Bummer it doesn't work. :(

I've submitted a ticket for the issue:
https://code.djangoproject.com/ticket/17314 Is there a developer that
can review it? If it is indeed a bug, I can probably fix it with some
direction.

Thanks,
jpk

jpk

unread,
Dec 7, 2011, 7:17:56 PM12/7/11
to geod...@googlegroups.com
In case it's useful, I found a workaround that doesn't need raw sql.

If you do the spatial filter, list() the resulting query set, and pass
that list to __in instead of the query set, the resulting query will
be functionally equivalent to if you hand't list()'d it, but avoid the
bug.

For example:

# Get all the SpatialThings with a location inside a polygon.
spatial_things = SpatialThing.objects.filter(location__contained=Polygon(...))

# Make a list out of the query set.
spatial_things_list = list(spatial_things)

# Get all the OtherThings that have a spatial_thing in spatial_things.
other_things = OtherThing.objects.filter(spatial_thing__in=spatial_things_list)

Of course, list() will load the results of the entire query into
memory, which you may or may not want. Additionally, the sql
generated by the filter for OtherThings will be a little different
than had you not list()'d the spatial query set. Instead of the
"WHERE "myapp_otherthing"."spatial_thing_id" IN (...)" portion of the
query being the nested spatial query, like "IN ( SELECT U0."id" FROM
"myapp_spatial_thing" U0 WHERE U0."location" @ ST_GeomFromEWKB(...)
)", it will be just a list of the id's of the objects in the list,
like "IN (2, 3, 5, 7, 11)". The implications of which I probably
don't understand, but I figure it's worth noting.

So for me, it's not as turbo-ghetto as dealing with raw sql, but still
naturally-aspirated-ghetto compared to just using the ORM the way God
intended. In any case, my offer as per my post to django-users still
stands: http://groups.google.com/group/django-users/browse_thread/thread/a698fc2fa3180835
:)

Cheers,
jpk

Reply all
Reply to author
Forward
0 new messages