Opened 3 days ago

Closed 27 hours ago

Last modified 27 hours ago

#36289 closed Bug (fixed)

Postgres bulk_create error when geometry is null or a different SRID

Reported by: Joshua Goodwin Owned by: Simon Charette
Component: Database layer (models, ORM) Version: 5.2
Severity: Release blocker Keywords:
Cc: Simon Charette, Mariusz Felisiak Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

I have a model with a geometry field like this:

from django.contrib.gis.db import models

class Garage(models.Model):
    name = models.CharField(max_length=100, blank=True)
    location = models.PointField(null=True, blank=True)

With Django 5.2 and PostgreSQL (17.4 / PostGIS 3.5.2), bulk_create fails when I try to more than one item with a null location:

Garage.objects.bulk_create([Garage(), Garage()])
InternalError: parse error - invalid geometry
LINE 1: ...stimes_garage" ("location") SELECT * FROM UNNEST(('{NULL,NUL...
                                                             ^
HINT:  "NU" <-- parse error at position 2 within geometry

or with an SRID other than the default

Garage.objects.bulk_create([Garage(location="SRID=29902;POINT(624210 307091)"), Garage(location="SRID=29902;POINT(624210 307091)")])
DataError: Geometry SRID (29902) does not match column SRID (4326)

This seems to be a regression in 5.2, maybe related to #35936 (Speeding up Postgres bulk_create by using unnest)

Change History (7)

comment:1 by Sarah Boyce, 3 days ago

Cc: Simon Charette Mariusz Felisiak added
Severity: NormalRelease blocker
Triage Stage: UnreviewedAccepted

Thank you for the report!

Replicated, regression in a16eedcf9c69d8a11d94cac1811018c5b996d491
Basic regression test if useful:

  • TabularUnified tests/gis_tests/geo3d/models.py

    a b class SimpleModel(models.Model):  
    5858
    5959
    6060class Point2D(SimpleModel):
    61     point = models.PointField()
     61    point = models.PointField(null=True)
    6262
    6363
    6464class Point3D(SimpleModel):
  • TabularUnified tests/gis_tests/geo3d/tests.py

    diff --git a/tests/gis_tests/geo3d/tests.py b/tests/gis_tests/geo3d/tests.py
    index b37deabb46..af772b07d6 100644
    a b class Geo3DTest(Geo3DLoadingHelper, TestCase):  
    206206        lm.save()
    207207        self.assertEqual(3, MultiPoint3D.objects.count())
    208208
     209    def bulk_create_point_field(self):
     210        objs = Point2D.objects.bulk_create([Point2D(), Point2D()])
     211        self.assertEqual(len(objs), 2)
     212
    209213    @skipUnlessDBFeature("supports_3d_functions")
Last edited 3 days ago by Sarah Boyce (previous) (diff)

comment:2 by Simon Charette, 3 days ago

The most simple solution is likely to adapt assemble_as_sql to disable the optimization if any field has a geometry db type.

comment:3 by Simon Charette, 2 days ago

Owner: set to Simon Charette
Status: newassigned

comment:4 by Simon Charette, 2 days ago

Has patch: set

comment:5 by Mariusz Felisiak, 28 hours ago

Triage Stage: AcceptedReady for checkin

comment:6 by Mariusz Felisiak <felisiak.mariusz@…>, 27 hours ago

Resolution: fixed
Status: assignedclosed

In 764af7a:

Fixed #36289 -- Fixed bulk_create() crash with nullable geometry fields on PostGIS.

Swapped to an allow list instead of a deny list for field types to
determine if the UNNEST optimization can be enabled to avoid further
surprises with other types that would require further specialization to
adapt.

Regression in a16eedcf9c69d8a11d94cac1811018c5b996d491.

Thanks Joshua Goodwin for the report and Sarah Boyce for the test.

comment:7 by Mariusz Felisiak <felisiak.mariusz@…>, 27 hours ago

In d9bf0d0:

[5.2.x] Fixed #36289 -- Fixed bulk_create() crash with nullable geometry fields on PostGIS.

Swapped to an allow list instead of a deny list for field types to
determine if the UNNEST optimization can be enabled to avoid further
surprises with other types that would require further specialization to
adapt.

Regression in a16eedcf9c69d8a11d94cac1811018c5b996d491.

Thanks Joshua Goodwin for the report and Sarah Boyce for the test.

Backport of 764af7a3d6c0b543dcf659a2c327f214da768fe4 from main

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