base.py 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. import sys
  2. from ctypes.util import find_library
  3. from django.conf import settings
  4. from django.core.exceptions import ImproperlyConfigured
  5. from django.db.backends.sqlite3.base import (Database,
  6. DatabaseWrapper as SQLiteDatabaseWrapper, SQLiteCursorWrapper)
  7. from django.contrib.gis.db.backends.spatialite.client import SpatiaLiteClient
  8. from django.contrib.gis.db.backends.spatialite.creation import SpatiaLiteCreation
  9. from django.contrib.gis.db.backends.spatialite.introspection import SpatiaLiteIntrospection
  10. from django.contrib.gis.db.backends.spatialite.operations import SpatiaLiteOperations
  11. from django.contrib.gis.db.backends.spatialite.schema import SpatialiteSchemaEditor
  12. from django.utils import six
  13. class DatabaseWrapper(SQLiteDatabaseWrapper):
  14. def __init__(self, *args, **kwargs):
  15. # Before we get too far, make sure pysqlite 2.5+ is installed.
  16. if Database.version_info < (2, 5, 0):
  17. raise ImproperlyConfigured('Only versions of pysqlite 2.5+ are '
  18. 'compatible with SpatiaLite and GeoDjango.')
  19. # Trying to find the location of the SpatiaLite library.
  20. # Here we are figuring out the path to the SpatiaLite library
  21. # (`libspatialite`). If it's not in the system library path (e.g., it
  22. # cannot be found by `ctypes.util.find_library`), then it may be set
  23. # manually in the settings via the `SPATIALITE_LIBRARY_PATH` setting.
  24. self.spatialite_lib = getattr(settings, 'SPATIALITE_LIBRARY_PATH',
  25. find_library('spatialite'))
  26. if not self.spatialite_lib:
  27. raise ImproperlyConfigured('Unable to locate the SpatiaLite library. '
  28. 'Make sure it is in your library path, or set '
  29. 'SPATIALITE_LIBRARY_PATH in your settings.'
  30. )
  31. super(DatabaseWrapper, self).__init__(*args, **kwargs)
  32. self.ops = SpatiaLiteOperations(self)
  33. self.client = SpatiaLiteClient(self)
  34. self.creation = SpatiaLiteCreation(self)
  35. self.introspection = SpatiaLiteIntrospection(self)
  36. def schema_editor(self, *args, **kwargs):
  37. "Returns a new instance of this backend's SchemaEditor"
  38. return SpatialiteSchemaEditor(self, *args, **kwargs)
  39. def get_new_connection(self, conn_params):
  40. conn = super(DatabaseWrapper, self).get_new_connection(conn_params)
  41. # Enabling extension loading on the SQLite connection.
  42. try:
  43. conn.enable_load_extension(True)
  44. except AttributeError:
  45. raise ImproperlyConfigured(
  46. 'The pysqlite library does not support C extension loading. '
  47. 'Both SQLite and pysqlite must be configured to allow '
  48. 'the loading of extensions to use SpatiaLite.')
  49. # Loading the SpatiaLite library extension on the connection, and returning
  50. # the created cursor.
  51. cur = conn.cursor(factory=SQLiteCursorWrapper)
  52. try:
  53. cur.execute("SELECT load_extension(%s)", (self.spatialite_lib,))
  54. except Exception as msg:
  55. new_msg = (
  56. 'Unable to load the SpatiaLite library extension '
  57. '"%s" because: %s') % (self.spatialite_lib, msg)
  58. six.reraise(ImproperlyConfigured, ImproperlyConfigured(new_msg), sys.exc_info()[2])
  59. cur.close()
  60. return conn