Spaces:
Running
Running
File size: 1,983 Bytes
57384dd | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | """Shared SQLite connection helper.
Centralizes what psycopg used to provide automatically: dict-shaped rows,
`with`-block commit/rollback/close semantics (including on `conn.cursor()`,
which stock sqlite3.Cursor does not support as a context manager), and
date/datetime round-tripping.
"""
from __future__ import annotations
import sqlite3
from datetime import date, datetime, timezone
from pathlib import Path
sqlite3.register_adapter(date, lambda d: d.isoformat())
sqlite3.register_adapter(
datetime,
lambda dt: (dt if dt.tzinfo else dt.replace(tzinfo=timezone.utc)).astimezone(timezone.utc).isoformat(),
)
sqlite3.register_converter("DATE", lambda v: date.fromisoformat(v.decode()))
sqlite3.register_converter("TIMESTAMP", lambda v: datetime.fromisoformat(v.decode().replace("Z", "+00:00")))
def _dict_row(cursor: sqlite3.Cursor, row: tuple) -> dict:
return dict(zip((column[0] for column in cursor.description), row))
class Cursor(sqlite3.Cursor):
def __enter__(self) -> "Cursor":
return self
def __exit__(self, *exc) -> None:
self.close()
class Connection(sqlite3.Connection):
def cursor(self, factory=None) -> Cursor:
return super().cursor(factory or Cursor)
def __exit__(self, *exc) -> None:
super().__exit__(*exc)
self.close()
def _resolve_path(database_url: str) -> str:
if "sqlite:///" in database_url:
return database_url.split("sqlite:///", 1)[-1]
return database_url
def connect(database_url: str) -> Connection:
path = _resolve_path(database_url)
if path != ":memory:":
Path(path).parent.mkdir(parents=True, exist_ok=True)
conn = sqlite3.connect(
path,
factory=Connection,
detect_types=sqlite3.PARSE_DECLTYPES,
timeout=30,
)
conn.row_factory = _dict_row
conn.execute("PRAGMA foreign_keys = ON")
conn.execute("PRAGMA journal_mode = WAL")
conn.execute("PRAGMA busy_timeout = 5000")
return conn
|