diff --git a/datasette/app.py b/datasette/app.py index 9f2b54c2..7a0f6b89 100644 --- a/datasette/app.py +++ b/datasette/app.py @@ -90,6 +90,9 @@ CONFIG_OPTIONS = ( ConfigOption("default_cache_ttl", 365 * 24 * 60 * 60, """ Default HTTP cache TTL (used in Cache-Control: max-age= header) """.strip()), + ConfigOption("cache_size_kb", 0, """ + SQLite cache size in KB (0 == use SQLite default) + """.strip()), ) DEFAULT_CONFIG = { option.name: option.default @@ -238,6 +241,8 @@ class Datasette: conn.enable_load_extension(True) for extension in self.sqlite_extensions: conn.execute("SELECT load_extension('{}')".format(extension)) + if self.config["cache_size_kb"]: + conn.execute('PRAGMA cache_size=-{}'.format(self.config["cache_size_kb"])) pm.hook.prepare_connection(conn=conn) def inspect(self): diff --git a/docs/config.rst b/docs/config.rst index 25bfd3d5..fe974a8f 100644 --- a/docs/config.rst +++ b/docs/config.rst @@ -110,3 +110,12 @@ Default HTTP caching max-age header in seconds, used for ``Cache-Control: max-ag :: datasette mydatabase.db --config default_cache_ttl:10 + +cache_size_kb +------------- + +Sets the amount of memory SQLite uses for its `per-connection cache `_, in KB. + +:: + + datasette mydatabase.db --config cache_size_kb:5000 diff --git a/tests/fixtures.py b/tests/fixtures.py index 6c23b815..3c2d9402 100644 --- a/tests/fixtures.py +++ b/tests/fixtures.py @@ -51,6 +51,13 @@ def app_client_returned_rows_matches_page_size(): yield from app_client(max_returned_rows=50) +@pytest.fixture(scope='session') +def app_client_larger_cache_size(): + yield from app_client(config={ + 'cache_size_kb': 2500, + }) + + def generate_compound_rows(num): for a, b, c in itertools.islice( itertools.product(string.ascii_lowercase, repeat=3), num @@ -114,6 +121,9 @@ METADATA = { 'primary_key_multiple_columns_explicit_label': { 'label_column': 'content2', }, + }, + 'queries': { + 'pragma_cache_size': 'PRAGMA cache_size;' } }, } diff --git a/tests/test_api.py b/tests/test_api.py index c90010ad..f2378005 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -1,6 +1,7 @@ from .fixtures import ( # noqa app_client, app_client_shorter_time_limit, + app_client_larger_cache_size, app_client_returned_rows_matches_page_size, generate_compound_rows, generate_sortable_rows, @@ -929,6 +930,7 @@ def test_config_json(app_client): "allow_sql": True, "default_cache_ttl": 365 * 24 * 60 * 60, "num_sql_threads": 3, + "cache_size_kb": 0, } == response.json @@ -1175,3 +1177,10 @@ def test_json_columns(app_client, extra_args, expected): path += extra_args response = app_client.get(path, gather_request=False) assert expected == response.json + + +def test_config_cache_size(app_client_larger_cache_size): + response = app_client_larger_cache_size.get( + '/test_tables/pragma_cache_size.json', gather_request=False + ) + assert [[-2500]] == response.json['rows']