--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

@ -1,4 +1,5 @@
import asyncio
from collections import namedtuple
from pathlib import Path
import janus
import queue
@ -22,6 +23,8 @@ from .inspect import inspect_hash
connections = threading.local()
AttachedDatabase = namedtuple("AttachedDatabase", ("seq", "name", "file"))
class Database:
def __init__(
@ -78,7 +81,7 @@ class Database:
conn.execute("PRAGMA query_only=1")
return conn
if self.is_memory:
return sqlite3.connect(":memory:")
return sqlite3.connect(":memory:", uri=True)
# mode=ro or immutable=1?
if self.is_mutable:
qs = "?mode=ro"
@ -243,6 +246,12 @@ class Database:
return None
return Path(self.path).stat().st_mtime_ns
async def attached_databases(self):
results = await self.execute(
"select seq, name, file from pragma_database_list() where seq > 0"
)
return [AttachedDatabase(*row) for row in results.rows]
async def table_exists(self, table):
results = await self.execute(
"select 1 from sqlite_master where type='table' and name=?", params=(table,)