Opened 5 years ago
Last modified 4 years ago
#31450 new Bug
Querying on ArrayField(PointField) returns string instead of list
Reported by: | Nitin Sangwan | Owned by: | |
---|---|---|---|
Component: | contrib.postgres | Version: | 3.0 |
Severity: | Normal | Keywords: | ArrayField, PointField |
Cc: | Simon Charette | Triage Stage: | Accepted |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | yes |
Easy pickings: | no | UI/UX: | no |
Description
The following code
from django.db import models from django.contrib.postgres.fields import ArrayField from django.contrib.gis.db.models import PointField class Foo(models.Model): bar = ArrayField(models.TextField) baz = ArrayField(PointField())
has this wrong behaviour:
x = Foo.objects.get(id=1) x.bar # => ['Foo', 'Bar'] x.baz # => '{HexRepresentationofPoint1,HexRepresentationofPoint2}'
Attachments (1)
Change History (7)
by , 5 years ago
Attachment: | postgis_tests.zip added |
---|
comment:1 by , 5 years ago
Triage Stage: | Unreviewed → Accepted |
---|
Thanks for the report. Reproduced at 578c03b276e435bcd3ce9eb17b81e85135c2d3f3 with the attached test case.
comment:2 by , 5 years ago
Has patch: | set |
---|---|
Owner: | set to |
Patch needs improvement: | set |
Status: | new → assigned |
comment:3 by , 5 years ago
Comment from the PR:
Thanks @Simon for your suggestion.
I've tried to create and register a new array type for geometry
based on your suggestion at #8453. here is the code:
def get_geometry_oids(connection_alias): with connections[connection_alias].cursor() as cursor: cursor.execute("SELECT typarray FROM pg_type WHERE typname = 'geometry'") return tuple(row[0] for row in cursor) ... geometry_oids = get_geometry_oids(connection.alias) new_type = psycopg2.extensions.new_type(geometry_oids, "geometry", caster) # caster is function to cast hex to geometry object array_type = psycopg2.extensions.new_array_type(geometry_oids, 'geometry[]', new_type) psycopg2.extensions.register_type(array_type, None)
The problem is that in caster
function, I get all items in array not one item. something like this:
0101000020E610000000000000000018400000000000003840:0101000020E610000000000000000014400000000000003740
which is represent two points that seprated by :
.
I've checed the column value in postgres console. for an array of points I got this:
{0101000020E6100000000000000000F03F0000000000000040:0101000020E6100000000000000000F03F0000000000000040}
While, I got below value for an array of chars:
{foo,bar}
the difference between two cases is for an array of points I got :
as a separator, but for an array of chars I got ,
.
I also tried to insert data from console to an array of points column by:
insert into test values (ARRAY[st_geomFromText('POINT(1 1)', 4326), st_geomFromText('POINT(1 1)', 4326)]);
the result was the same(:
as separator).
Do you have any idea?
comment:4 by , 5 years ago
Cc: | added |
---|
comment:5 by , 5 years ago
I spent a few hours trying to figure it out but it looks like there might be something wrong with psycopg2
. When registering an array type for geometry
from the retrieved oid it simply doesn't get invoked for columns of type geometry(POINT, srid)[]
behind ArrayField(PointField())
.
Hasan your code is registering an array type and a scalar type for the same oid
, you want to register a type for the scalar oid and an array type for array oid. Look at how get_hstore_oids
and psycopg2.extras.register_hstore
do it.
comment:6 by , 4 years ago
Owner: | removed |
---|---|
Status: | assigned → new |
Reproduce test case for #31450