Opened 8 years ago

Last modified 8 years ago

#28160 closed Bug

Can't start with django.contrib.gis.gdal.HAS_GDAL = False due to ImportError of GDALRaster — at Version 1

Reported by: Tom Kazimiers Owned by: nobody
Component: GIS Version: 1.10
Severity: Normal Keywords: GIS, GDAL, Contrib, Bug
Cc: Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by Tom Kazimiers)

Under some circumstances django.contrib.gis.gdal.HAS_GDAL is False. This can be due to not having GDAL installed in the first place or by overriding one's OS name (and thereby causing the test in django.contrib.gis.gdal.__init__.py to result in an exception which in turns causes HAS_GDAL = False).¹

Now with HAS_GDAL = False, I can't start Django anymore (neither the shell or any other command), because I get the following error:

django.core.exceptions.ImproperlyConfigured: 'postgresql' isn't an available database backend.
Try using 'django.db.backends.XXX', where XXX is one of:
    'mysql', 'oracle', 'postgresql', 'sqlite3'
Error was: No module named postgresql.base

Digging a bit deeper into this reveals this is actually an ImportError: Error was: cannot import name GDALRaster. Using other django.contrib.gis functionality should also work without GDAL (and did so in the past).

The problem seems to be that in commit bbfad84dd980a97174c3b061a3d1b5f1373c380d (here) a new import has been added to django/contrib/gis/db/backends/postgis/operations.py, which tries to import GDALRaster: from django.contrib.gis.gdal import GDALRaster. This of course fails with HAS_GDAL = False, because GDALRaster has never been defined when HAS_GDAL was set false due to an (expected) exception in django/django/contrib/gis/gdal/libgdal.py, which is imported before from django.contrib.gis.gdal.raster.source import GDALRaster in django/django/contrib/gis/gdal/__init__.py.

So maybe the import in django/contrib/gis/db/backends/postgis/operations.py and the use of GDALRaster should be conditional and only run if HAS_GDAL = True. I can provide a patch if wanted.

This is a problem in both Django 1.10 and 1.11.

A workaround for this is to run this code before the (postgis) database driver is loaded (e.g. through an own custom database driver that just sub-classes the original):

import django.contrib.gis.gdal
class GDALRasterMock(object):
    pass
django.contrib.gis.gdal.GDALRaster = GDALRasterMock

¹ In my project I need to do the latter to disable GDAL support completely, because loading the library conflicts with pgmagick on Ubuntu and there is no other way to disable GDAL, but this shouldn't matter here. It would be nice though to have a way to force HAS_GDAL = False, because unlike said in django/django/contrib/gis/gdal/__init__.py, setting GDAL_LIBRARY_PATH='/null/path' doesn't work (the automatic OS checks override this).

Change History (1)

comment:1 by Tom Kazimiers, 8 years ago

Description: modified (diff)

Add monkey-patch workaround

Note: See TracTickets for help on using tickets.
Back to Top