--load-extension option for sqlite-utils query, closes #134

This commit is contained in:
Simon Willison 2020-08-21 13:54:11 -07:00
commit 7e9aad7e1c
3 changed files with 50 additions and 2 deletions

View file

@ -83,6 +83,11 @@ You can run queries against a temporary in-memory database by passing ``:memory:
$ sqlite-utils :memory: "select sqlite_version()"
[{"sqlite_version()": "3.29.0"}]
You can load SQLite extension modules using the `--load-extension` option::
$ sqlite-utils :memory: "select spatialite_version()" --load-extension=/usr/local/lib/mod_spatialite.dylib
[{"spatialite_version()": "4.3.0a"}]
.. _cli_json_values:
Nested JSON values

View file

@ -719,9 +719,29 @@ def drop_view(path, view):
type=(str, str),
help="Named :parameters for SQL query",
)
def query(path, sql, nl, arrays, csv, no_headers, table, fmt, json_cols, raw, param):
@click.option(
"--load-extension", multiple=True, help="SQLite extensions to load",
)
def query(
path,
sql,
nl,
arrays,
csv,
no_headers,
table,
fmt,
json_cols,
raw,
param,
load_extension,
):
"Execute SQL query and return the results as JSON"
db = sqlite_utils.Database(path)
if load_extension:
db.conn.enable_load_extension(True)
for ext in load_extension:
db.conn.load_extension(ext)
with db.conn:
cursor = db.conn.execute(sql, dict(param))
if cursor.description is None:

View file

@ -4,7 +4,7 @@ from click.testing import CliRunner
import json
import os
import pytest
from sqlite_utils.utils import sqlite3
from sqlite_utils.utils import sqlite3, find_spatialite
from .utils import collapse_whitespace
@ -885,6 +885,29 @@ def test_query_raw(db_path, content, is_binary):
assert result.output == str(content)
@pytest.mark.skipif(not find_spatialite(), reason="Could not find SpatiaLite extension")
@pytest.mark.skipif(
not hasattr(sqlite3.Connection, "enable_load_extension"),
reason="sqlite3.Connection missing enable_load_extension",
)
def test_query_load_extension():
# Without --load-extension:
result = CliRunner().invoke(cli.cli, [":memory:", "select spatialite_version()"])
assert result.exit_code == 1
assert "no such function: spatialite_version" in repr(result)
# With --load-extension:
result = CliRunner().invoke(
cli.cli,
[
":memory:",
"select spatialite_version()",
"--load-extension={}".format(find_spatialite()),
],
)
assert result.exit_code == 0, result.stdout
assert ["spatialite_version()"] == list(json.loads(result.output)[0].keys())
def test_query_memory_does_not_create_file(tmpdir):
owd = os.getcwd()
try: