1
0
mirror of https://github.com/django/django.git synced 2025-10-24 06:06:09 +00:00

Fixed #30020 -- Fixed reading nulls with LayerMapping.

This commit is contained in:
Kathryn Killebrew
2019-01-31 19:50:16 -05:00
committed by Tim Graham
parent 6da28d5edf
commit 75d627888b
9 changed files with 302 additions and 26 deletions

View File

@@ -1,3 +1,4 @@
import datetime
import os
import unittest
from copy import copy
@@ -13,8 +14,9 @@ from django.db import connection
from django.test import TestCase, override_settings
from .models import (
City, County, CountyFeat, ICity1, ICity2, Interstate, Invalid, State,
city_mapping, co_mapping, cofeat_mapping, inter_mapping,
City, County, CountyFeat, DoesNotAllowNulls, HasNulls, ICity1, ICity2,
Interstate, Invalid, State, city_mapping, co_mapping, cofeat_mapping,
has_nulls_mapping, inter_mapping,
)
shp_path = os.path.realpath(os.path.join(os.path.dirname(__file__), os.pardir, 'data'))
@@ -22,6 +24,7 @@ city_shp = os.path.join(shp_path, 'cities', 'cities.shp')
co_shp = os.path.join(shp_path, 'counties', 'counties.shp')
inter_shp = os.path.join(shp_path, 'interstates', 'interstates.shp')
invalid_shp = os.path.join(shp_path, 'invalid', 'emptypoints.shp')
has_nulls_geojson = os.path.join(shp_path, 'has_nulls', 'has_nulls.geojson')
# Dictionaries to hold what's expected in the county shapefile.
NAMES = ['Bexar', 'Galveston', 'Harris', 'Honolulu', 'Pueblo']
@@ -321,6 +324,59 @@ class LayerMapTest(TestCase):
self.assertIsNotNone(hu.mpoly)
self.assertEqual(hu.mpoly.ogr.num_coords, 449)
def test_null_number_imported(self):
"""LayerMapping import of GeoJSON with a null numeric value."""
lm = LayerMapping(HasNulls, has_nulls_geojson, has_nulls_mapping)
lm.save()
self.assertEqual(HasNulls.objects.count(), 3)
self.assertEqual(HasNulls.objects.filter(num=0).count(), 1)
self.assertEqual(HasNulls.objects.filter(num__isnull=True).count(), 1)
def test_null_string_imported(self):
"Test LayerMapping import of GeoJSON with a null string value."
lm = LayerMapping(HasNulls, has_nulls_geojson, has_nulls_mapping)
lm.save()
self.assertEqual(HasNulls.objects.filter(name='None').count(), 0)
num_empty = 1 if connection.features.interprets_empty_strings_as_nulls else 0
self.assertEqual(HasNulls.objects.filter(name='').count(), num_empty)
self.assertEqual(HasNulls.objects.filter(name__isnull=True).count(), 1)
def test_nullable_boolean_imported(self):
"""LayerMapping import of GeoJSON with a nullable boolean value."""
lm = LayerMapping(HasNulls, has_nulls_geojson, has_nulls_mapping)
lm.save()
self.assertEqual(HasNulls.objects.filter(boolean=True).count(), 1)
self.assertEqual(HasNulls.objects.filter(boolean=False).count(), 1)
self.assertEqual(HasNulls.objects.filter(boolean__isnull=True).count(), 1)
def test_nullable_datetime_imported(self):
"""LayerMapping import of GeoJSON with a nullable date/time value."""
lm = LayerMapping(HasNulls, has_nulls_geojson, has_nulls_mapping)
lm.save()
self.assertEqual(HasNulls.objects.filter(datetime__lt=datetime.date(1994, 8, 15)).count(), 1)
self.assertEqual(HasNulls.objects.filter(datetime='2018-11-29T03:02:52').count(), 1)
self.assertEqual(HasNulls.objects.filter(datetime__isnull=True).count(), 1)
def test_uuids_imported(self):
"""LayerMapping import of GeoJSON with UUIDs."""
lm = LayerMapping(HasNulls, has_nulls_geojson, has_nulls_mapping)
lm.save()
self.assertEqual(HasNulls.objects.filter(uuid='1378c26f-cbe6-44b0-929f-eb330d4991f5').count(), 1)
def test_null_number_imported_not_allowed(self):
"""
LayerMapping import of GeoJSON with nulls to fields that don't permit
them.
"""
lm = LayerMapping(DoesNotAllowNulls, has_nulls_geojson, has_nulls_mapping)
lm.save(silent=True)
# When a model fails to save due to IntegrityError (null in non-null
# column), subsequent saves fail with "An error occurred in the current
# transaction. You can't execute queries until the end of the 'atomic'
# block." On Oracle and MySQL, the one object that did load appears in
# this count. On other databases, no records appear.
self.assertLessEqual(DoesNotAllowNulls.objects.count(), 1)
class OtherRouter:
def db_for_read(self, model, **hints):