You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

base.py 2.9KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. from ctypes.util import find_library
  2. from django.conf import settings
  3. from django.core.exceptions import ImproperlyConfigured
  4. from django.db.backends.sqlite3.base import (
  5. DatabaseWrapper as SQLiteDatabaseWrapper,
  6. )
  7. from .client import SpatiaLiteClient
  8. from .features import DatabaseFeatures
  9. from .introspection import SpatiaLiteIntrospection
  10. from .operations import SpatiaLiteOperations
  11. from .schema import SpatialiteSchemaEditor
  12. class DatabaseWrapper(SQLiteDatabaseWrapper):
  13. SchemaEditorClass = SpatialiteSchemaEditor
  14. # Classes instantiated in __init__().
  15. client_class = SpatiaLiteClient
  16. features_class = DatabaseFeatures
  17. introspection_class = SpatiaLiteIntrospection
  18. ops_class = SpatiaLiteOperations
  19. def __init__(self, *args, **kwargs):
  20. # Trying to find the location of the SpatiaLite library.
  21. # Here we are figuring out the path to the SpatiaLite library
  22. # (`libspatialite`). If it's not in the system library path (e.g., it
  23. # cannot be found by `ctypes.util.find_library`), then it may be set
  24. # manually in the settings via the `SPATIALITE_LIBRARY_PATH` setting.
  25. self.lib_spatialite_paths = [name for name in [
  26. getattr(settings, 'SPATIALITE_LIBRARY_PATH', None),
  27. 'mod_spatialite.so',
  28. 'mod_spatialite',
  29. find_library('spatialite'),
  30. ] if name is not None]
  31. super().__init__(*args, **kwargs)
  32. def get_new_connection(self, conn_params):
  33. conn = super().get_new_connection(conn_params)
  34. # Enabling extension loading on the SQLite connection.
  35. try:
  36. conn.enable_load_extension(True)
  37. except AttributeError:
  38. raise ImproperlyConfigured(
  39. 'SpatiaLite requires SQLite to be configured to allow '
  40. 'extension loading.'
  41. )
  42. # Load the SpatiaLite library extension on the connection.
  43. for path in self.lib_spatialite_paths:
  44. try:
  45. conn.load_extension(path)
  46. except Exception:
  47. if getattr(settings, 'SPATIALITE_LIBRARY_PATH', None):
  48. raise ImproperlyConfigured(
  49. 'Unable to load the SpatiaLite library extension '
  50. 'as specified in your SPATIALITE_LIBRARY_PATH setting.'
  51. )
  52. continue
  53. else:
  54. break
  55. else:
  56. raise ImproperlyConfigured(
  57. 'Unable to load the SpatiaLite library extension. '
  58. 'Library names tried: %s' % ', '.join(self.lib_spatialite_paths)
  59. )
  60. return conn
  61. def prepare_database(self):
  62. super().prepare_database()
  63. # Check if spatial metadata have been initialized in the database
  64. with self.cursor() as cursor:
  65. cursor.execute("PRAGMA table_info(geometry_columns);")
  66. if cursor.fetchall() == []:
  67. cursor.execute("SELECT InitSpatialMetaData(1)")