Multi-Tenant Router¶
Route requests to dedicated SQLite configs per tenant slug.
uv run python docs/examples/patterns/multi_tenant/router.py
Source¶
1"""Dispatch requests to dedicated SQLite configs per tenant."""
2
3from sqlspec.adapters.sqlite import SqliteConfig
4from sqlspec.core import SQL
5
6__all__ = ("TenantRouter", "main")
7
8
9TENANTS: "tuple[str, ...]" = ("acme", "orbital")
10
11
12class TenantRouter:
13 """Maintain isolated SqliteConfig instances for each tenant slug."""
14
15 def __init__(self, tenants: "tuple[str, ...]") -> None:
16 self._configs = {
17 slug: SqliteConfig(connection_config={"database": ":memory:"}, bind_key=slug) for slug in tenants
18 }
19
20 def insert_article(self, slug: str, title: str) -> None:
21 config = self._configs[slug]
22 with config.provide_session() as session:
23 session.execute(
24 """
25 CREATE TABLE IF NOT EXISTS articles (
26 id INTEGER PRIMARY KEY AUTOINCREMENT,
27 title TEXT NOT NULL
28 )
29 """
30 )
31 session.execute("INSERT INTO articles (title) VALUES (:title)", {"title": title})
32
33 def list_titles(self, slug: str) -> "list[str]":
34 config = self._configs[slug]
35 with config.provide_session() as session:
36 result = session.execute(SQL("SELECT title FROM articles ORDER BY id"))
37 return [row["title"] for row in result.all()]
38
39
40def main() -> None:
41 """Insert one record per tenant and print the isolated results."""
42 router = TenantRouter(TENANTS)
43 router.insert_article("acme", "Acme onboarding")
44 router.insert_article("orbital", "Orbital checklist")
45 payload: dict[str, list[str]] = {slug: router.list_titles(slug) for slug in TENANTS}
46 print(payload)
47
48
49if __name__ == "__main__":
50 main()