Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fixed #10888 -- May now insert NULL `GeometryField` values on Oracle.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@10631 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 44c062344f77708fd68189cbd80792daf524e5a6 1 parent d682978
Justin Bronn authored April 24, 2009
2  django/contrib/gis/db/backend/oracle/field.py
@@ -94,7 +94,7 @@ def get_placeholder(self, value):
94 94
         SDO_CS.TRANSFORM() function call.
95 95
         """
96 96
         if value is None:
97  
-            return '%s'
  97
+            return 'NULL'
98 98
         elif value.srid != self.srid:
99 99
             # Adding Transform() to the SQL placeholder.
100 100
             return '%s(SDO_GEOMETRY(%%s, %s), %s)' % (TRANSFORM, value.srid, self.srid)
4  django/contrib/gis/db/models/manager.py
... ...
@@ -1,5 +1,6 @@
1 1
 from django.db.models.manager import Manager
2 2
 from django.contrib.gis.db.models.query import GeoQuerySet
  3
+from django.contrib.gis.db.models.sql.subqueries import insert_query
3 4
 
4 5
 class GeoManager(Manager):
5 6
     "Overrides Manager to return Geographic QuerySets."
@@ -86,3 +87,6 @@ def union(self, *args, **kwargs):
86 87
 
87 88
     def unionagg(self, *args, **kwargs):
88 89
         return self.get_query_set().unionagg(*args, **kwargs)
  90
+
  91
+    def _insert(self, values, **kwargs):
  92
+        return insert_query(self.model, values, **kwargs)
39  django/contrib/gis/db/models/sql/subqueries.py
... ...
@@ -0,0 +1,39 @@
  1
+from django.contrib.gis.db.backend import SpatialBackend
  2
+from django.db.models.query import insert_query
  3
+
  4
+if SpatialBackend.oracle:
  5
+    from django.db import connection
  6
+    from django.db.models.sql.subqueries import InsertQuery
  7
+
  8
+    class OracleGeoInsertQuery(InsertQuery):
  9
+        def insert_values(self, insert_values, raw_values=False):
  10
+            """
  11
+            This routine is overloaded from InsertQuery so that no parameter is
  12
+            passed into cx_Oracle for NULL geometries.  The reason is that
  13
+            cx_Oracle has no way to bind Oracle object values (like
  14
+            MDSYS.SDO_GEOMETRY).
  15
+            """
  16
+            placeholders, values = [], []
  17
+            for field, val in insert_values:
  18
+                if hasattr(field, 'get_placeholder'):
  19
+                    ph = field.get_placeholder(val)
  20
+                else:
  21
+                    ph = '%s'
  22
+
  23
+                placeholders.append(ph)
  24
+                self.columns.append(field.column)
  25
+
  26
+                # If 'NULL' for the placeholder, omit appending None
  27
+                # to the values list (which is used for db params).
  28
+                if not ph == 'NULL':
  29
+                    values.append(val)
  30
+            if raw_values:
  31
+                self.values.extend(values)
  32
+            else:
  33
+                self.params += tuple(values)
  34
+                self.values.extend(placeholders)
  35
+
  36
+    def insert_query(model, values, return_id=False, raw_values=False):
  37
+        query = OracleGeoInsertQuery(model, connection)
  38
+        query.insert_values(values, raw_values)
  39
+        return query.execute_sql(return_id)
25  django/contrib/gis/tests/geoapp/tests.py
@@ -30,7 +30,7 @@ def test01_initial_sql(self):
30 30
             data_dir = os.path.join(os.path.dirname(__file__), 'sql')
31 31
             def get_file(wkt_file):
32 32
                 return os.path.join(data_dir, wkt_file)
33  
-
  33
+            State(name='Puerto Rico', poly=None).save()
34 34
             State(name='Colorado', poly=fromfile(get_file('co.wkt'))).save()
35 35
             State(name='Kansas', poly=fromfile(get_file('ks.wkt'))).save()
36 36
             Country(name='Texas', mpoly=fromfile(get_file('tx.wkt'))).save()
@@ -39,13 +39,7 @@ def get_file(wkt_file):
39 39
         # Ensuring that data was loaded from initial SQL.
40 40
         self.assertEqual(2, Country.objects.count())
41 41
         self.assertEqual(8, City.objects.count())
42  
-
43  
-        # Only PostGIS can handle NULL geometries
44  
-        if SpatialBackend.postgis or SpatialBackend.spatialite:
45  
-            n_state = 3
46  
-        else:
47  
-            n_state = 2
48  
-        self.assertEqual(n_state, State.objects.count())
  42
+        self.assertEqual(3, State.objects.count())
49 43
 
50 44
     def test02_proxy(self):
51 45
         "Testing Lazy-Geometry support (using the GeometryProxy)."
@@ -369,10 +363,6 @@ def test11_lookup_insert_transform(self):
369 363
             m1.save()
370 364
             self.assertEqual(-1, m1.geom.srid)
371 365
 
372  
-    # Oracle does not support NULL geometries in its spatial index for
373  
-    # some routines (e.g., SDO_GEOM.RELATE).
374  
-    @no_oracle
375  
-    @no_spatialite
376 366
     def test12_null_geometries(self):
377 367
         "Testing NULL geometry support, and the `isnull` lookup type."
378 368
         if DISABLE: return
@@ -391,9 +381,14 @@ def test12_null_geometries(self):
391 381
         self.assertEqual(True, 'Kansas' in state_names)
392 382
 
393 383
         # Saving another commonwealth w/a NULL geometry.
394  
-        if not SpatialBackend.oracle:
395  
-            # TODO: Fix saving w/NULL geometry on Oracle.
396  
-            State(name='Northern Mariana Islands', poly=None).save()
  384
+        nmi = State.objects.create(name='Northern Mariana Islands', poly=None)
  385
+        self.assertEqual(nmi.poly, None)
  386
+
  387
+        # Assigning a geomery and saving -- then UPDATE back to NULL.
  388
+        nmi.poly = 'POLYGON((0 0,1 0,1 1,1 0,0 0))'
  389
+        nmi.save()
  390
+        State.objects.filter(name='Northern Mariana Islands').update(poly=None)
  391
+        self.assertEqual(None, State.objects.get(name='Northern Mariana Islands').poly)
397 392
 
398 393
     @no_oracle # No specific `left` or `right` operators in Oracle.
399 394
     @no_spatialite # No `left` or `right` operators in SpatiaLite.

0 notes on commit 44c0623

Please sign in to comment.
Something went wrong with that request. Please try again.