mirror of
https://github.com/simonw/datasette.git
synced 2025-12-10 16:51:24 +01:00
--load-extension=spatialite shortcut, closes #1028
This commit is contained in:
parent
a4def0b8db
commit
6aa5886379
6 changed files with 54 additions and 6 deletions
|
|
@ -49,12 +49,14 @@ from .utils import (
|
||||||
display_actor,
|
display_actor,
|
||||||
escape_css_string,
|
escape_css_string,
|
||||||
escape_sqlite,
|
escape_sqlite,
|
||||||
|
find_spatialite,
|
||||||
format_bytes,
|
format_bytes,
|
||||||
module_from_path,
|
module_from_path,
|
||||||
parse_metadata,
|
parse_metadata,
|
||||||
resolve_env_secrets,
|
resolve_env_secrets,
|
||||||
sqlite3,
|
sqlite3,
|
||||||
to_css_class,
|
to_css_class,
|
||||||
|
SpatialiteNotFound,
|
||||||
)
|
)
|
||||||
from .utils.asgi import (
|
from .utils.asgi import (
|
||||||
AsgiLifespan,
|
AsgiLifespan,
|
||||||
|
|
@ -242,7 +244,14 @@ class Datasette:
|
||||||
metadata = parse_metadata(fp.read())
|
metadata = parse_metadata(fp.read())
|
||||||
self._metadata = metadata or {}
|
self._metadata = metadata or {}
|
||||||
self.sqlite_functions = []
|
self.sqlite_functions = []
|
||||||
self.sqlite_extensions = sqlite_extensions or []
|
self.sqlite_extensions = []
|
||||||
|
for extension in sqlite_extensions or []:
|
||||||
|
# Resolve spatialite, if requested
|
||||||
|
if extension == "spatialite":
|
||||||
|
# Could raise SpatialiteNotFound
|
||||||
|
self.sqlite_extensions.append(find_spatialite())
|
||||||
|
else:
|
||||||
|
self.sqlite_extensions.append(extension)
|
||||||
if config_dir and (config_dir / "templates").is_dir() and not template_dir:
|
if config_dir and (config_dir / "templates").is_dir() and not template_dir:
|
||||||
template_dir = str((config_dir / "templates").resolve())
|
template_dir = str((config_dir / "templates").resolve())
|
||||||
self.template_dir = template_dir
|
self.template_dir = template_dir
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ from .utils import (
|
||||||
SpatialiteConnectionProblem,
|
SpatialiteConnectionProblem,
|
||||||
temporary_docker_directory,
|
temporary_docker_directory,
|
||||||
value_as_boolean,
|
value_as_boolean,
|
||||||
|
SpatialiteNotFound,
|
||||||
StaticMount,
|
StaticMount,
|
||||||
ValueAsBooleanError,
|
ValueAsBooleanError,
|
||||||
)
|
)
|
||||||
|
|
@ -78,7 +79,6 @@ def cli():
|
||||||
"--load-extension",
|
"--load-extension",
|
||||||
envvar="SQLITE_EXTENSIONS",
|
envvar="SQLITE_EXTENSIONS",
|
||||||
multiple=True,
|
multiple=True,
|
||||||
type=click.Path(exists=True, resolve_path=True),
|
|
||||||
help="Path to a SQLite extension to load",
|
help="Path to a SQLite extension to load",
|
||||||
)
|
)
|
||||||
def inspect(files, inspect_file, sqlite_extensions):
|
def inspect(files, inspect_file, sqlite_extensions):
|
||||||
|
|
@ -299,7 +299,6 @@ def uninstall(packages, yes):
|
||||||
"--load-extension",
|
"--load-extension",
|
||||||
envvar="SQLITE_EXTENSIONS",
|
envvar="SQLITE_EXTENSIONS",
|
||||||
multiple=True,
|
multiple=True,
|
||||||
type=click.Path(exists=True, resolve_path=True),
|
|
||||||
help="Path to a SQLite extension to load",
|
help="Path to a SQLite extension to load",
|
||||||
)
|
)
|
||||||
@click.option(
|
@click.option(
|
||||||
|
|
@ -433,7 +432,10 @@ def serve(
|
||||||
kwargs["config_dir"] = pathlib.Path(files[0])
|
kwargs["config_dir"] = pathlib.Path(files[0])
|
||||||
files = []
|
files = []
|
||||||
|
|
||||||
ds = Datasette(files, **kwargs)
|
try:
|
||||||
|
ds = Datasette(files, **kwargs)
|
||||||
|
except SpatialiteNotFound:
|
||||||
|
raise click.ClickException("Could not find SpatiaLite extension")
|
||||||
|
|
||||||
if return_instance:
|
if return_instance:
|
||||||
# Private utility mechanism for writing unit tests
|
# Private utility mechanism for writing unit tests
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,12 @@ RUN apt-get update && \
|
||||||
ENV SQLITE_EXTENSIONS /usr/lib/x86_64-linux-gnu/mod_spatialite.so
|
ENV SQLITE_EXTENSIONS /usr/lib/x86_64-linux-gnu/mod_spatialite.so
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# Can replace with sqlite-utils when I add that dependency
|
||||||
|
SPATIALITE_PATHS = (
|
||||||
|
"/usr/lib/x86_64-linux-gnu/mod_spatialite.so",
|
||||||
|
"/usr/local/lib/mod_spatialite.dylib",
|
||||||
|
)
|
||||||
|
|
||||||
# Can replace this with Column from sqlite_utils when I add that dependency
|
# Can replace this with Column from sqlite_utils when I add that dependency
|
||||||
Column = namedtuple(
|
Column = namedtuple(
|
||||||
"Column", ("cid", "name", "type", "notnull", "default_value", "is_pk")
|
"Column", ("cid", "name", "type", "notnull", "default_value", "is_pk")
|
||||||
|
|
@ -971,3 +977,15 @@ def display_actor(actor):
|
||||||
if actor.get(key):
|
if actor.get(key):
|
||||||
return actor[key]
|
return actor[key]
|
||||||
return str(actor)
|
return str(actor)
|
||||||
|
|
||||||
|
|
||||||
|
class SpatialiteNotFound(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# Can replace with sqlite-utils when I add that dependency
|
||||||
|
def find_spatialite():
|
||||||
|
for path in SPATIALITE_PATHS:
|
||||||
|
if os.path.exists(path):
|
||||||
|
return path
|
||||||
|
raise SpatialiteNotFound
|
||||||
|
|
|
||||||
|
|
@ -170,7 +170,7 @@ module, use the following command::
|
||||||
docker run -p 8001:8001 -v `pwd`:/mnt \
|
docker run -p 8001:8001 -v `pwd`:/mnt \
|
||||||
datasetteproject/datasette \
|
datasetteproject/datasette \
|
||||||
datasette -p 8001 -h 0.0.0.0 /mnt/fixtures.db \
|
datasette -p 8001 -h 0.0.0.0 /mnt/fixtures.db \
|
||||||
--load-extension=/usr/local/lib/mod_spatialite.so
|
--load-extension=spatialite
|
||||||
|
|
||||||
You can confirm that SpatiaLite is successfully loaded by visiting
|
You can confirm that SpatiaLite is successfully loaded by visiting
|
||||||
http://127.0.0.1:8001/-/versions
|
http://127.0.0.1:8001/-/versions
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,14 @@ The `SpatiaLite module <https://www.gaia-gis.it/fossil/libspatialite/index>`_ fo
|
||||||
|
|
||||||
To use it with Datasette, you need to install the ``mod_spatialite`` dynamic library. This can then be loaded into Datasette using the ``--load-extension`` command-line option.
|
To use it with Datasette, you need to install the ``mod_spatialite`` dynamic library. This can then be loaded into Datasette using the ``--load-extension`` command-line option.
|
||||||
|
|
||||||
|
Datasette can look for SpatiaLite in common installation locations if you run it like this::
|
||||||
|
|
||||||
|
datasette --load-extension=spatialite
|
||||||
|
|
||||||
|
If SpatiaLite is in another location, use the full path to the extension instead::
|
||||||
|
|
||||||
|
datasette --load-extension=/usr/local/lib/mod_spatialite.dylib
|
||||||
|
|
||||||
Installation
|
Installation
|
||||||
============
|
============
|
||||||
|
|
||||||
|
|
@ -25,7 +33,7 @@ This will install the ``spatialite`` command-line tool and the ``mod_spatialite`
|
||||||
|
|
||||||
You can now run Datasette like so::
|
You can now run Datasette like so::
|
||||||
|
|
||||||
datasette --load-extension=/usr/local/lib/mod_spatialite.dylib
|
datasette --load-extension=spatialite
|
||||||
|
|
||||||
Installing SpatiaLite on Linux
|
Installing SpatiaLite on Linux
|
||||||
------------------------------
|
------------------------------
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,17 @@ def test_spatialite_error_if_attempt_to_open_spatialite():
|
||||||
assert "trying to load a SpatiaLite database" in result.output
|
assert "trying to load a SpatiaLite database" in result.output
|
||||||
|
|
||||||
|
|
||||||
|
@mock.patch("datasette.utils.SPATIALITE_PATHS", ["/does/not/exist"])
|
||||||
|
def test_spatialite_error_if_cannot_find_load_extension_spatialite():
|
||||||
|
runner = CliRunner()
|
||||||
|
result = runner.invoke(
|
||||||
|
cli, ["serve", str(pathlib.Path(__file__).parent / "spatialite.db"),
|
||||||
|
"--load-extension", "spatialite"]
|
||||||
|
)
|
||||||
|
assert result.exit_code != 0
|
||||||
|
assert "Could not find SpatiaLite extension" in result.output
|
||||||
|
|
||||||
|
|
||||||
def test_plugins_cli(app_client):
|
def test_plugins_cli(app_client):
|
||||||
runner = CliRunner()
|
runner = CliRunner()
|
||||||
result1 = runner.invoke(cli, ["plugins"])
|
result1 = runner.invoke(cli, ["plugins"])
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue