Datasette brings its SQLite explorer into the browser
Datasette 0.62 supports the Pyodide runtime behind Datasette Lite. A browser can run the Python application and query downloaded SQLite files through the existing interface.
Publishing a database for exploration usually means publishing an application that can query it. Datasette Lite changes where that application can execute. Datasette 0.62, released on August 14, adds compatibility with Pyodide, the WebAssembly Python runtime behind the browser application. A user can work with SQLite through Datasette's interface without installing a local Python environment or requiring a dedicated Datasette server for the session.
This is the regular Python application running in a different environment. Simon Willison introduced Datasette Lite in May, describing a web worker that loads Python, installs Datasette, downloads database files, and routes interface requests internally. The August release makes Pyodide compatibility part of a stable Datasette version. It should not be mistaken for the first announcement of Lite itself.
I like this use of SQLite because it keeps a database useful as a transferable file. Exploration does not inherently require moving the data into a new storage service. The browser supplies an execution environment around the file, while SQL remains the way to express questions about its contents.
The application runs behind an internal request interface
Willison's explanation describes loading SQLite files into Pyodide's in-memory filesystem. The web worker retains a Datasette object and handles requested paths through its internal client. Status, content type, and response content return to the page. This reuses the application's request handling without putting a listening HTTP server between the browser page and the Python code running inside it.
That arrangement separates an HTTP-shaped application interface from a network deployment. A request path can still identify a table page or a SQL result. The program handling it does not have to live on a remote host. For this use, the internal client provides a way to reuse rendering and query logic that the application already implements.
The database download still depends on ordinary browser access rules. The May article requires suitable CORS headers for a database fetched from another origin. Moving query execution into the browser therefore removes one server requirement without making every file on the web automatically readable by the application. The database publisher needs to make the intended download accessible.
Non-threaded execution makes the runtime boundary concrete
The database implementation in 0.62 contains explicit support for non-threaded mode. It retains read and write connections for that mode. When no executor is configured, a write function runs against the retained connection directly. The threaded path instead has separate queue machinery.
This is a useful example of making an application's execution policy configurable while retaining its data-access code. The caller still requests an operation through the database abstraction. The implementation chooses how to run it under the available runtime. That distinction gives an application a better chance of working outside the process and threading assumptions of its original server environment.
The same file distinguishes named in-memory databases, temporary memory databases, and file-backed connections. Read connections to mutable files use a read-only URI. Connections to immutable files use the immutable option. These branches show that a database's location and mutation policy are deliberate inputs, not facts that every query method has to rediscover.
The new release also offers a --nolock option for read-only databases. That is a separate server-side connection setting, visible in the file-backed connection logic. Pyodide compatibility should not be understood as a reason to apply every new connection option to every deployment. They address different execution environments.
Queries remain shareable application state
The SQL-query documentation shipped with 0.62 describes an editor that can execute SELECT queries when the appropriate permission is allowed. A query is reflected in its page URL, and the interface can expose results as JSON. These capabilities make the explorer more useful than a fixed set of precomputed reports.
Named parameters also become form inputs. A query can state the relationship being inspected while leaving selected values to the reader. The documentation specifies that supplied parameter values are strings, and numeric comparisons should use an explicit cast where required. A simple query against a table containing a numeric temperature column could use this form.
SELECT station, temperature
FROM readings
WHERE temperature > cast(:minimum as real)
ORDER BY temperature DESC;
The SQL describes the operation, and minimum is a value supplied through the interface. The explicit cast records how the string input participates in the numeric comparison. This is a small example of the semantic work a useful database explorer performs beyond displaying rows.
Canned queries provide another option. The versioned documentation allows a database publisher to place named SQL statements in metadata and give each a URL. A canned query can include named parameters too. That supports a designed entry point for a dataset while retaining the flexibility of SQL for the operation itself. The metadata can also provide a title and description, giving the reader context about what the query answers before they change its input values.
Reusing the application changes distribution costs
The browser runtime has a loading cost. The May explanation calls attention to the size of the runtime download, so avoiding installation does not mean eliminating resource use. Downloading a database also differs from submitting a small query to a server that already holds it. The appropriate distribution model depends on the size of the data and the work the reader needs to perform.
The 0.62 release additionally makes database downloads conditional through ETags. That is useful for the conventional hosted application and reinforces the role of the database file as a distributable object. A browser-hosted explorer and a server-hosted explorer can have different execution costs while presenting related ways to inspect the same relational contents.
I regard the stable runtime support as the substantive step in this release. The project can reuse a Python application, its request interface, and SQLite querying in a browser environment. A dataset author gains another way to make data inspectable, while the reader retains access to SQL and parameterized questions instead of being limited to the reports chosen in advance.