--crossdb option for joining across databases (#1232)

* Test for cross-database join, refs #283
* Warn if --crossdb used with more than 10 DBs, refs #283
* latest.datasette.io demo of --crossdb joins, refs #283
* Show attached databases on /_memory page, refs #283
* Documentation for cross-database queries, refs #283
This commit is contained in:
Simon Willison 2021-02-18 14:09:12 -08:00 committed by GitHub
commit 6f41c8a2be
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 215 additions and 8 deletions

View file

@ -41,6 +41,7 @@ Options:
--pdb Launch debugger on any errors
-o, --open Open Datasette in your web browser
--create Create database files if they do not exist
--crossdb Enable cross-database joins using the /_memory database
--ssl-keyfile TEXT SSL key file
--ssl-certfile TEXT SSL certificate file
--help Show this message and exit.

View file

@ -677,6 +677,9 @@ The ``Database`` class also provides properties and methods for introspecting th
``db.is_memory`` - boolean
Is this database an in-memory database?
``await db.attached_databases()`` - list of named tuples
Returns a list of additional databases that have been connected to this database using the SQLite ATTACH command. Each named tuple has fields ``seq``, ``name`` and ``file``.
``await db.table_exists(table)`` - boolean
Check if a table called ``table`` exists.

View file

@ -389,3 +389,34 @@ detect if there should be another page.
Since the where clause acts against the index on the primary key, the query is
extremely fast even for records that are a long way into the overall pagination
set.
.. _cross_database_quereies:
Cross-database queries
----------------------
SQLite has the ability to run queries that join across multiple databases. Up to ten databases can be attached to a single SQLite connection and queried together.
Datasette can execute joins across multiple databases if it is started with the ``--crossdb`` option::
datasette fixtures.db extra_database.db --crossdb
If it is started in this way, the ``/_memory`` page can be used to execute queries that join across multiple databases.
References to tables in attached databases should be preceeded by the database name and a period.
For example, this query will show a list of tables across both of the above databases:
.. code-block:: sql
select
'fixtures' as database, *
from
[fixtures].sqlite_master
union
select
'extra_database' as database, *
from
[extra_database].sqlite_master
`Try that out here <https://latest.datasette.io/_memory?sql=select%0D%0A++%27fixtures%27+as+database%2C+*%0D%0Afrom%0D%0A++%5Bfixtures%5D.sqlite_master%0D%0Aunion%0D%0Aselect%0D%0A++%27extra_database%27+as+database%2C+*%0D%0Afrom%0D%0A++%5Bextra_database%5D.sqlite_master>`__.