[1.0.X] Fixed various Oracle errata and test failures present in this branch (including not going to 11).
Backport of Oracle-related changes from trunk in r10197. git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.0.X@10614 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
ed5e3c3d2b
commit
f110f91a03
@ -201,7 +201,7 @@ class GeoQuery(sql.Query):
|
||||
"""
|
||||
if SpatialBackend.oracle:
|
||||
# Running through Oracle's first.
|
||||
value = super(GeoQuery, self).convert_values(value, field)
|
||||
value = super(GeoQuery, self).convert_values(value, field or GeomField())
|
||||
if isinstance(field, DistanceField):
|
||||
# Using the field's distance attribute, can instantiate
|
||||
# `Distance` with the right context.
|
||||
@ -325,15 +325,22 @@ class GeoQuery(sql.Query):
|
||||
return self._check_geo_field(self.model, field_name)
|
||||
|
||||
### Field Classes for `convert_values` ####
|
||||
class AreaField(object):
|
||||
class BaseField(object):
|
||||
def get_internal_type(self):
|
||||
"Overloaded method so OracleQuery.convert_values doesn't balk."
|
||||
return None
|
||||
|
||||
if SpatialBackend.oracle: BaseField.empty_strings_allowed = False
|
||||
|
||||
class AreaField(BaseField):
|
||||
def __init__(self, area_att):
|
||||
self.area_att = area_att
|
||||
|
||||
class DistanceField(object):
|
||||
class DistanceField(BaseField):
|
||||
def __init__(self, distance_att):
|
||||
self.distance_att = distance_att
|
||||
|
||||
# Rather than use GeometryField (which requires a SQL query
|
||||
# upon instantiation), use this lighter weight class.
|
||||
class GeomField(object):
|
||||
class GeomField(BaseField):
|
||||
pass
|
||||
|
@ -13,7 +13,7 @@ def geo_suite():
|
||||
from django.contrib.gis.utils import HAS_GEOIP
|
||||
|
||||
# Tests that require use of a spatial database (e.g., creation of models)
|
||||
test_models = ['geoapp',]
|
||||
test_models = ['geoapp', 'layermap', 'relatedapp']
|
||||
|
||||
# Tests that do not require setting up and tearing down a spatial database.
|
||||
test_suite_names = [
|
||||
@ -21,15 +21,8 @@ def geo_suite():
|
||||
'test_measure',
|
||||
]
|
||||
if HAS_GDAL:
|
||||
if oracle:
|
||||
# TODO: There's a problem with `select_related` and GeoQuerySet on
|
||||
# Oracle -- e.g., GeoModel.objects.distance(geom, field_name='fk__point')
|
||||
# doesn't work so we don't test `relatedapp`.
|
||||
test_models += ['distapp', 'layermap']
|
||||
elif postgis:
|
||||
test_models += ['distapp', 'layermap', 'relatedapp']
|
||||
elif mysql:
|
||||
test_models += ['relatedapp', 'layermap']
|
||||
if oracle or postgis:
|
||||
test_models.append('distapp')
|
||||
|
||||
test_suite_names += [
|
||||
'test_gdal_driver',
|
||||
|
@ -115,8 +115,12 @@ class DistanceTest(unittest.TestCase):
|
||||
# with different projected coordinate systems.
|
||||
dist1 = SouthTexasCity.objects.distance(lagrange, field_name='point')
|
||||
dist2 = SouthTexasCity.objects.distance(lagrange) # Using GEOSGeometry parameter
|
||||
dist3 = SouthTexasCityFt.objects.distance(lagrange.ewkt) # Using EWKT string parameter.
|
||||
dist4 = SouthTexasCityFt.objects.distance(lagrange)
|
||||
if oracle:
|
||||
dist_qs = [dist1, dist2]
|
||||
else:
|
||||
dist3 = SouthTexasCityFt.objects.distance(lagrange.ewkt) # Using EWKT string parameter.
|
||||
dist4 = SouthTexasCityFt.objects.distance(lagrange)
|
||||
dist_qs = [dist1, dist2, dist3, dist4]
|
||||
|
||||
# Original query done on PostGIS, have to adjust AlmostEqual tolerance
|
||||
# for Oracle.
|
||||
@ -124,7 +128,7 @@ class DistanceTest(unittest.TestCase):
|
||||
else: tol = 5
|
||||
|
||||
# Ensuring expected distances are returned for each distance queryset.
|
||||
for qs in [dist1, dist2, dist3, dist4]:
|
||||
for qs in dist_qs:
|
||||
for i, c in enumerate(qs):
|
||||
self.assertAlmostEqual(m_distances[i], c.distance.m, tol)
|
||||
self.assertAlmostEqual(ft_distances[i], c.distance.survey_ft, tol)
|
||||
@ -194,8 +198,16 @@ class DistanceTest(unittest.TestCase):
|
||||
# (thus, Houston and Southside place will be excluded as tested in
|
||||
# the `test02_dwithin` above).
|
||||
qs1 = SouthTexasCity.objects.filter(point__distance_gte=(self.stx_pnt, D(km=7))).filter(point__distance_lte=(self.stx_pnt, D(km=20)))
|
||||
qs2 = SouthTexasCityFt.objects.filter(point__distance_gte=(self.stx_pnt, D(km=7))).filter(point__distance_lte=(self.stx_pnt, D(km=20)))
|
||||
for qs in qs1, qs2:
|
||||
|
||||
# Oracle 11 incorrectly thinks spatial reference system for the
|
||||
# SouthTexasCityFt model is not projected, so omit.
|
||||
if oracle:
|
||||
dist_qs = (qs1,)
|
||||
else:
|
||||
qs2 = SouthTexasCityFt.objects.filter(point__distance_gte=(self.stx_pnt, D(km=7))).filter(point__distance_lte=(self.stx_pnt, D(km=20)))
|
||||
dist_qs = (qs1, qs2)
|
||||
|
||||
for qs in dist_qs:
|
||||
cities = self.get_names(qs)
|
||||
self.assertEqual(cities, ['Bellaire', 'Pearland', 'West University Place'])
|
||||
|
||||
|
@ -150,7 +150,7 @@ class GeoModelTest(unittest.TestCase):
|
||||
if SpatialBackend.oracle:
|
||||
# No precision parameter for Oracle :-/
|
||||
import re
|
||||
gml_regex = re.compile(r'<gml:Point srsName="SDO:4326" xmlns:gml="http://www.opengis.net/gml"><gml:coordinates decimal="\." cs="," ts=" ">-104.60925199\d+,38.25500\d+ </gml:coordinates></gml:Point>')
|
||||
gml_regex = re.compile(r'<gml:Point srsName="SDO:4326" xmlns:gml="http://www.opengis.net/gml"><gml:coordinates decimal="\." cs="," ts=" ">-104.60925\d+,38.25500\d+ </gml:coordinates></gml:Point>')
|
||||
for ptown in [ptown1, ptown2]:
|
||||
self.assertEqual(True, bool(gml_regex.match(ptown.gml)))
|
||||
else:
|
||||
|
@ -1,6 +1,6 @@
|
||||
import os, unittest
|
||||
from django.contrib.gis.geos import *
|
||||
from django.contrib.gis.tests.utils import no_mysql, postgis
|
||||
from django.contrib.gis.tests.utils import no_mysql, no_oracle, oracle, postgis
|
||||
from django.conf import settings
|
||||
from models import City, Location, DirectoryEntry
|
||||
|
||||
@ -19,6 +19,7 @@ class RelatedGeoModelTest(unittest.TestCase):
|
||||
c = City(name=name, state=state, location=loc)
|
||||
c.save()
|
||||
|
||||
@no_oracle # There are problems w/spatial Oracle pagination and select_related()
|
||||
def test02_select_related(self):
|
||||
"Testing `select_related` on geographic models (see #7126)."
|
||||
qs1 = City.objects.all()
|
||||
@ -33,6 +34,7 @@ class RelatedGeoModelTest(unittest.TestCase):
|
||||
self.assertEqual(Point(lon, lat), c.location.point)
|
||||
|
||||
@no_mysql
|
||||
@no_oracle # Pagination problem is implicated in this test as well.
|
||||
def test03_transform_related(self):
|
||||
"Testing the `transform` GeoQuerySet method on related geographic models."
|
||||
# All the transformations are to state plane coordinate systems using
|
||||
@ -71,22 +73,42 @@ class RelatedGeoModelTest(unittest.TestCase):
|
||||
#self.assertEqual(nqueries, len(connection.queries))
|
||||
|
||||
@no_mysql
|
||||
def test04_related_aggregate(self):
|
||||
"Testing the `extent` and `unionagg` GeoQuerySet aggregates on related geographic models."
|
||||
if postgis:
|
||||
# One for all locations, one that excludes Roswell.
|
||||
all_extent = (-104.528060913086, 33.0583305358887,-79.4607315063477, 40.1847610473633)
|
||||
txpa_extent = (-97.51611328125, 33.0583305358887,-79.4607315063477, 40.1847610473633)
|
||||
e1 = City.objects.extent(field_name='location__point')
|
||||
e2 = City.objects.exclude(name='Roswell').extent(field_name='location__point')
|
||||
for ref, e in [(all_extent, e1), (txpa_extent, e2)]:
|
||||
for ref_val, e_val in zip(ref, e): self.assertAlmostEqual(ref_val, e_val)
|
||||
@no_oracle
|
||||
def test04a_related_extent_aggregate(self):
|
||||
"Testing the `extent` GeoQuerySet aggregates on related geographic models."
|
||||
# One for all locations, one that excludes Roswell.
|
||||
all_extent = (-104.528060913086, 33.0583305358887,-79.4607315063477, 40.1847610473633)
|
||||
txpa_extent = (-97.51611328125, 33.0583305358887,-79.4607315063477, 40.1847610473633)
|
||||
e1 = City.objects.extent(field_name='location__point')
|
||||
e2 = City.objects.exclude(name='Roswell').extent(field_name='location__point')
|
||||
tol = 9
|
||||
for ref, e in [(all_extent, e1), (txpa_extent, e2)]:
|
||||
for ref_val, e_val in zip(ref, e): self.assertAlmostEqual(ref_val, e_val, tol)
|
||||
|
||||
@no_mysql
|
||||
def test04b_related_union_aggregate(self):
|
||||
"Testing the `unionagg` GeoQuerySet aggregates on related geographic models."
|
||||
# These are the points that are components of the aggregate geographic
|
||||
# union that is returned.
|
||||
p1 = Point(-104.528056, 33.387222)
|
||||
p2 = Point(-97.516111, 33.058333)
|
||||
p3 = Point(-79.460734, 40.18476)
|
||||
|
||||
# Creating the reference union geometry depending on the spatial backend,
|
||||
# as Oracle will have a different internal ordering of the component
|
||||
# geometries than PostGIS. The second union aggregate is for a union
|
||||
# query that includes limiting information in the WHERE clause (in other
|
||||
# words a `.filter()` precedes the call to `.unionagg()`).
|
||||
if oracle:
|
||||
ref_u1 = MultiPoint(p3, p1, p2, srid=4326)
|
||||
ref_u2 = MultiPoint(p3, p2, srid=4326)
|
||||
else:
|
||||
ref_u1 = MultiPoint(p1, p2, p3, srid=4326)
|
||||
ref_u2 = MultiPoint(p2, p3, srid=4326)
|
||||
|
||||
# The second union is for a query that has something in the WHERE clause.
|
||||
ref_u1 = GEOSGeometry('MULTIPOINT(-104.528056 33.387222,-97.516111 33.058333,-79.460734 40.18476)', 4326)
|
||||
ref_u2 = GEOSGeometry('MULTIPOINT(-97.516111 33.058333,-79.460734 40.18476)', 4326)
|
||||
u1 = City.objects.unionagg(field_name='location__point')
|
||||
u2 = City.objects.exclude(name='Roswell').unionagg(field_name='location__point')
|
||||
|
||||
self.assertEqual(ref_u1, u1)
|
||||
self.assertEqual(ref_u2, u2)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user