Skip to content

Commit

Permalink
Raise exception when attempting to write schema not supported by driver
Browse files Browse the repository at this point in the history
  • Loading branch information
snorfalorpagus committed Jun 5, 2018
1 parent 8128275 commit 797e5e7
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 15 deletions.
29 changes: 28 additions & 1 deletion fiona/collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from fiona.ogrext import (
calc_gdal_version_num, get_gdal_version_num, get_gdal_release_name)
from fiona.ogrext import buffer_to_virtual_file, remove_virtual_file, GEOMETRY_TYPES
from fiona.errors import DriverError, SchemaError, CRSError, UnsupportedGeometryTypeError
from fiona.errors import (DriverError, SchemaError, CRSError, UnsupportedGeometryTypeError, DriverSupportError)
from fiona._drivers import driver_count, GDALEnv
from fiona.drvsupport import supported_drivers, AWSGDALEnv
from six import string_types, binary_type
Expand Down Expand Up @@ -133,6 +133,8 @@ def __init__(self, path, mode='r', driver=None, schema=None, crs=None,
raise SchemaError("schema lacks: geometry")
self._schema = schema

self._check_schema_driver_support()

if crs_wkt:
self._crs_wkt = crs_wkt
elif crs:
Expand Down Expand Up @@ -395,6 +397,31 @@ def bounds(self):
self._bounds = self.session.get_extent()
return self._bounds

def _check_schema_driver_support(self):
"""Check support for the schema against the driver
See GH#572 for discussion.
"""
gdal_version_major = get_gdal_version_num() // 1000000
for field in self._schema["properties"]:
field_type = field.split(":")[0]
if self._driver == "ESRI Shapefile":
if field_type == "datetime":
raise DriverSupportError("ESRI Shapefile does not support datetime fields")
elif field_type == "time":
raise DriverSupportError("ESRI Shapefile does not support time fields")
elif self._driver == "GPKG":
if field_type == "time":
raise DriverSupportError("GPKG does not support time fields")
elif self._driver == "GeoJSON":
if gdal_version_major == 1:
if field_type == "date":
warnings.warn("GeoJSON driver in GDAL 1.x silently converts date to string in non-standard format")
elif field_type == "datetime":
warnings.warn("GeoJSON driver in GDAL 1.x silently converts datetime to string in non-standard format")
elif field_type == "time":
warnings.warn("GeoJSON driver in GDAL 1.x silently converts time to string")

def flush(self):
"""Flush the buffer."""
if self.session is not None:
Expand Down
4 changes: 4 additions & 0 deletions fiona/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ class DriverIOError(IOError):
"""A format specific driver error."""


class DriverSupportError(DriverIOError):
"""Driver does not support schema"""


class DatasetDeleteError(IOError):
"""Failure to delete a dataset"""

Expand Down
32 changes: 18 additions & 14 deletions tests/test_datetime.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import pytest
import tempfile, shutil
import os
from fiona.errors import DriverSupportError
from .conftest import requires_gpkg

GDAL_MAJOR_VER = fiona.get_gdal_version_num() // 1000000
Expand Down Expand Up @@ -139,11 +140,13 @@ def write_data(self, driver):
def test_shapefile(self):
# datetime is silently converted to date
driver = "ESRI Shapefile"
schema, features = self.write_data(driver)

with pytest.raises(DriverSupportError):
schema, features = self.write_data(driver)

assert schema["properties"]["datetime"] == "date"
assert features[0]["properties"]["datetime"] == "2018-03-25"
assert features[1]["properties"]["datetime"] is None
# assert schema["properties"]["datetime"] == "date"
# assert features[0]["properties"]["datetime"] == "2018-03-25"
# assert features[1]["properties"]["datetime"] is None

@requires_gpkg
def test_gpkg(self):
Expand Down Expand Up @@ -219,25 +222,26 @@ def write_data(self, driver):
return schema, features

def test_shapefile(self):
# attempting to write time field to shapefile raises KeyError
# this is a bug in fiona
# no support for time fields
driver = "ESRI Shapefile"
with pytest.raises(KeyError):
with pytest.raises(DriverSupportError):
self.write_data(driver)

@requires_gpkg
def test_gpkg(self):
# GDAL 2: time field is silently converted to string
# GDAL 1: time field dropped completely
driver = "GPKG"
schema, features = self.write_data(driver)

with pytest.raises(DriverSupportError):
schema, features = self.write_data(driver)

if GDAL_MAJOR_VER >= 2:
assert schema["properties"]["time"] == "str"
assert features[0]["properties"]["time"] == TIME_EXAMPLE
assert features[1]["properties"]["time"] is None
else:
assert "time" not in schema["properties"]
# if GDAL_MAJOR_VER >= 2:
# assert schema["properties"]["time"] == "str"
# assert features[0]["properties"]["time"] == TIME_EXAMPLE
# assert features[1]["properties"]["time"] is None
# else:
# assert "time" not in schema["properties"]

def test_geojson(self):
# GDAL 1: time field silently converted to string
Expand Down

0 comments on commit 797e5e7

Please sign in to comment.