Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

[1.0.X] Fixed #10888 -- May now insert NULL `GeometryField` values on…

… Oracle.

Backport of r10631 from trunk.


git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.0.X@10632 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit a7bfcba5db4789ea22b7d6d2288d45e0aed5afae 1 parent 3b3c05d
Justin Bronn authored April 24, 2009
2  django/contrib/gis/db/backend/oracle/field.py
@@ -95,7 +95,7 @@ def get_placeholder(self, value):
95 95
         SDO_CS.TRANSFORM() function call.
96 96
         """
97 97
         if value is None:
98  
-            return '%s'
  98
+            return 'NULL'
99 99
         elif value.srid != self._srid:
100 100
             # Adding Transform() to the SQL placeholder.
101 101
             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."
@@ -80,3 +81,6 @@ def union(self, *args, **kwargs):
80 81
 
81 82
     def unionagg(self, *args, **kwargs):
82 83
         return self.get_query_set().unionagg(*args, **kwargs)
  84
+
  85
+    def _insert(self, values, **kwargs):
  86
+        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)
22  django/contrib/gis/tests/geoapp/tests.py
@@ -27,7 +27,7 @@ def test01_initial_sql(self):
27 27
             data_dir = os.path.join(os.path.dirname(__file__), 'sql')
28 28
             def get_file(wkt_file):
29 29
                 return os.path.join(data_dir, wkt_file)
30  
-
  30
+            State(name='Puerto Rico', poly=None).save()
31 31
             State(name='Colorado', poly=fromfile(get_file('co.wkt'))).save()
32 32
             State(name='Kansas', poly=fromfile(get_file('ks.wkt'))).save()
33 33
             Country(name='Texas', mpoly=fromfile(get_file('tx.wkt'))).save()
@@ -36,11 +36,7 @@ def get_file(wkt_file):
36 36
         # Ensuring that data was loaded from initial SQL.
37 37
         self.assertEqual(2, Country.objects.count())
38 38
         self.assertEqual(8, City.objects.count())
39  
-
40  
-        # Oracle cannot handle NULL geometry values w/certain queries.
41  
-        if SpatialBackend.oracle: n_state = 2
42  
-        else: n_state = 3
43  
-        self.assertEqual(n_state, State.objects.count())
  39
+        self.assertEqual(3, State.objects.count())
44 40
 
45 41
     def test02_proxy(self):
46 42
         "Testing Lazy-Geometry support (using the GeometryProxy)."
@@ -308,9 +304,6 @@ def test11_lookup_insert_transform(self):
308 304
         m1.save()
309 305
         self.assertEqual(-1, m1.geom.srid)
310 306
 
311  
-    # Oracle does not support NULL geometries in its spatial index for
312  
-    # some routines (e.g., SDO_GEOM.RELATE).
313  
-    @no_oracle
314 307
     def test12_null_geometries(self):
315 308
         "Testing NULL geometry support, and the `isnull` lookup type."
316 309
         if DISABLE: return
@@ -329,9 +322,14 @@ def test12_null_geometries(self):
329 322
         self.assertEqual(True, 'Kansas' in state_names)
330 323
 
331 324
         # Saving another commonwealth w/a NULL geometry.
332  
-        if not SpatialBackend.oracle:
333  
-            # TODO: Fix saving w/NULL geometry on Oracle.
334  
-            State(name='Northern Mariana Islands', poly=None).save()
  325
+        nmi = State.objects.create(name='Northern Mariana Islands', poly=None)
  326
+        self.assertEqual(nmi.poly, None)
  327
+
  328
+        # Assigning a geomery and saving -- then UPDATE back to NULL.
  329
+        nmi.poly = 'POLYGON((0 0,1 0,1 1,1 0,0 0))'
  330
+        nmi.save()
  331
+        State.objects.filter(name='Northern Mariana Islands').update(poly=None)
  332
+        self.assertEqual(None, State.objects.get(name='Northern Mariana Islands').poly)
335 333
 
336 334
     @no_oracle # No specific `left` or `right` operators in Oracle.
337 335
     def test13_left_right(self):

0 notes on commit a7bfcba

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