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
This commit is contained in:
parent
d6829782d0
commit
44c062344f
|
@ -94,7 +94,7 @@ class OracleSpatialField(Field):
|
|||
SDO_CS.TRANSFORM() function call.
|
||||
"""
|
||||
if value is None:
|
||||
return '%s'
|
||||
return 'NULL'
|
||||
elif value.srid != self.srid:
|
||||
# Adding Transform() to the SQL placeholder.
|
||||
return '%s(SDO_GEOMETRY(%%s, %s), %s)' % (TRANSFORM, value.srid, self.srid)
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
from django.db.models.manager import Manager
|
||||
from django.contrib.gis.db.models.query import GeoQuerySet
|
||||
from django.contrib.gis.db.models.sql.subqueries import insert_query
|
||||
|
||||
class GeoManager(Manager):
|
||||
"Overrides Manager to return Geographic QuerySets."
|
||||
|
@ -86,3 +87,6 @@ class GeoManager(Manager):
|
|||
|
||||
def unionagg(self, *args, **kwargs):
|
||||
return self.get_query_set().unionagg(*args, **kwargs)
|
||||
|
||||
def _insert(self, values, **kwargs):
|
||||
return insert_query(self.model, values, **kwargs)
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
from django.contrib.gis.db.backend import SpatialBackend
|
||||
from django.db.models.query import insert_query
|
||||
|
||||
if SpatialBackend.oracle:
|
||||
from django.db import connection
|
||||
from django.db.models.sql.subqueries import InsertQuery
|
||||
|
||||
class OracleGeoInsertQuery(InsertQuery):
|
||||
def insert_values(self, insert_values, raw_values=False):
|
||||
"""
|
||||
This routine is overloaded from InsertQuery so that no parameter is
|
||||
passed into cx_Oracle for NULL geometries. The reason is that
|
||||
cx_Oracle has no way to bind Oracle object values (like
|
||||
MDSYS.SDO_GEOMETRY).
|
||||
"""
|
||||
placeholders, values = [], []
|
||||
for field, val in insert_values:
|
||||
if hasattr(field, 'get_placeholder'):
|
||||
ph = field.get_placeholder(val)
|
||||
else:
|
||||
ph = '%s'
|
||||
|
||||
placeholders.append(ph)
|
||||
self.columns.append(field.column)
|
||||
|
||||
# If 'NULL' for the placeholder, omit appending None
|
||||
# to the values list (which is used for db params).
|
||||
if not ph == 'NULL':
|
||||
values.append(val)
|
||||
if raw_values:
|
||||
self.values.extend(values)
|
||||
else:
|
||||
self.params += tuple(values)
|
||||
self.values.extend(placeholders)
|
||||
|
||||
def insert_query(model, values, return_id=False, raw_values=False):
|
||||
query = OracleGeoInsertQuery(model, connection)
|
||||
query.insert_values(values, raw_values)
|
||||
return query.execute_sql(return_id)
|
|
@ -30,7 +30,7 @@ class GeoModelTest(unittest.TestCase):
|
|||
data_dir = os.path.join(os.path.dirname(__file__), 'sql')
|
||||
def get_file(wkt_file):
|
||||
return os.path.join(data_dir, wkt_file)
|
||||
|
||||
State(name='Puerto Rico', poly=None).save()
|
||||
State(name='Colorado', poly=fromfile(get_file('co.wkt'))).save()
|
||||
State(name='Kansas', poly=fromfile(get_file('ks.wkt'))).save()
|
||||
Country(name='Texas', mpoly=fromfile(get_file('tx.wkt'))).save()
|
||||
|
@ -39,13 +39,7 @@ class GeoModelTest(unittest.TestCase):
|
|||
# Ensuring that data was loaded from initial SQL.
|
||||
self.assertEqual(2, Country.objects.count())
|
||||
self.assertEqual(8, City.objects.count())
|
||||
|
||||
# Only PostGIS can handle NULL geometries
|
||||
if SpatialBackend.postgis or SpatialBackend.spatialite:
|
||||
n_state = 3
|
||||
else:
|
||||
n_state = 2
|
||||
self.assertEqual(n_state, State.objects.count())
|
||||
self.assertEqual(3, State.objects.count())
|
||||
|
||||
def test02_proxy(self):
|
||||
"Testing Lazy-Geometry support (using the GeometryProxy)."
|
||||
|
@ -369,10 +363,6 @@ class GeoModelTest(unittest.TestCase):
|
|||
m1.save()
|
||||
self.assertEqual(-1, m1.geom.srid)
|
||||
|
||||
# Oracle does not support NULL geometries in its spatial index for
|
||||
# some routines (e.g., SDO_GEOM.RELATE).
|
||||
@no_oracle
|
||||
@no_spatialite
|
||||
def test12_null_geometries(self):
|
||||
"Testing NULL geometry support, and the `isnull` lookup type."
|
||||
if DISABLE: return
|
||||
|
@ -391,9 +381,14 @@ class GeoModelTest(unittest.TestCase):
|
|||
self.assertEqual(True, 'Kansas' in state_names)
|
||||
|
||||
# Saving another commonwealth w/a NULL geometry.
|
||||
if not SpatialBackend.oracle:
|
||||
# TODO: Fix saving w/NULL geometry on Oracle.
|
||||
State(name='Northern Mariana Islands', poly=None).save()
|
||||
nmi = State.objects.create(name='Northern Mariana Islands', poly=None)
|
||||
self.assertEqual(nmi.poly, None)
|
||||
|
||||
# Assigning a geomery and saving -- then UPDATE back to NULL.
|
||||
nmi.poly = 'POLYGON((0 0,1 0,1 1,1 0,0 0))'
|
||||
nmi.save()
|
||||
State.objects.filter(name='Northern Mariana Islands').update(poly=None)
|
||||
self.assertEqual(None, State.objects.get(name='Northern Mariana Islands').poly)
|
||||
|
||||
@no_oracle # No specific `left` or `right` operators in Oracle.
|
||||
@no_spatialite # No `left` or `right` operators in SpatiaLite.
|
||||
|
|
Loading…
Reference in New Issue