-
-
Notifications
You must be signed in to change notification settings - Fork 772
Description
The current _internal
database is used by Datasette core to cache info about databases/tables/columns/foreign keys of databases in a Datasette instance. It's a temporary database created at startup, that can only be seen by the root user. See an example _internal
DB here, after logging in as root.
The current _internal
database has a few rough edges:
- It's part of
datasette.databases
, so many plugins have to specifically exclude_internal
from their queries examples here - It's only used by Datasette core and can't be used by plugins or 3rd parties
- It's created from scratch at startup and stored in memory. Why is fine, the performance is great, but persistent storage would be nice.
Additionally, it would be really nice if plugins could use this _internal
database to store their own configuration, secrets, and settings. For example:
datasette-auth-tokens
creates a_datasette_auth_tokens
table to store auth token metadata. This could be moved into the_internal
database to avoid writing to the gues databasedatasette-socrata
creates asocrata_imports
table, which also can be in_internal
datasette-upload-csvs
creates a_csv_progress_
table, which can be in_internal
datasette-write-ui
wants to have the ability for users to toggle whether a table appears editable, which can be either indatasette.yaml
or on-the-fly by storing config in_internal
In general, these are specific features that Datasette plugins would have access to if there was a central internal database they could read/write to:
- Dynamic configuration. Changing the
datasette.yaml
file works, but can be tedious to restart the server every time. Plugins can define their own configuration table in_internal
, and could read/write to it to store configuration based on user actions (cell menu click, API access, etc.) - Caching. If a plugin or Datasette Core needs to cache some expensive computation, they can store it inside
_internal
(possibly as a temporary table) instead of managing their own caching solution. - Audit logs. If a plugin performs some sensitive operations, they can log usage info to
_internal
for others to audit later. - Long running process status. Many plugins (
datasette-upload-csvs
,datasette-litestream
,datasette-socrata
) perform tasks that run for a really long time, and want to give continue status updates to the user. They can store this info inside_internal
- Safer authentication. Passwords and authentication plugins usually store credentials/hashed secrets in configuration files or environment variables, which can be difficult to handle. Now, they can store them in
_internal
Proposal
- We remove
_internal
fromdatasette.databases
property. - We add new
datasette.get_internal_db()
method that returns the_internal
database, for plugins to use - We add a new
--internal internal.db
flag. If provided, then the_internal
DB will be sourced from that file, and further updates will be persisted to that file (instead of an in-memory database) - When creating internal.db, create a new
_datasette_internal
table to mark it a an "datasette internal database" - In
datasette serve
, we check for the existence of the_datasette_internal
table. If it exists, we assume the user provided that file in error and raise an error. This is to limit the chance that someone accidentally publishes their internal database to the internet. We could optionally add a--unsafe-allow-internal
flag (or database plugin) that allows someone to do this if they really want to.
New features unlocked with this
These features don't really need a standardized _internal
table per-say (plugins could currently configure their own long-time storage features if they really wanted to), but it would make it much simpler to create these kinds of features with a persistent application database.
datasette-comments
: A plugin for commenting on rows or specific values in a database. Comment contents + threads + email notification info can be stored in_internal
- Bookmarks: "Bookmarking" an SQL query could be stored in
_internal
, or a URL link shortener - Webhooks: If a plugin wants to either consume a webhook or create a new one, they can store hashed credentials/API endpoints in
_internal