|
1 | 1 | from __future__ import annotations |
2 | 2 |
|
3 | 3 | import os |
| 4 | +import sqlite3 |
4 | 5 | import tempfile |
5 | 6 | from contextlib import contextmanager |
6 | 7 | from datetime import datetime, timezone |
|
18 | 19 | Text, |
19 | 20 | UniqueConstraint, |
20 | 21 | create_engine, |
| 22 | + event, |
21 | 23 | ) |
22 | 24 | from sqlalchemy.orm import ( |
23 | 25 | DeclarativeBase, |
@@ -390,19 +392,46 @@ def _resolve_database_url(raw_url: str) -> str: |
390 | 392 | return f"sqlite:///{candidate}" |
391 | 393 |
|
392 | 394 |
|
| 395 | +def _is_sqlite_url(url: str) -> bool: |
| 396 | + return url.startswith("sqlite:///") |
| 397 | + |
| 398 | + |
| 399 | +def _sqlite_connect_args() -> dict: |
| 400 | + return { |
| 401 | + "check_same_thread": False, |
| 402 | + "timeout": 30, |
| 403 | + } |
| 404 | + |
| 405 | + |
393 | 406 | RESOLVED_DATABASE_URL = _resolve_database_url(SETTINGS.database_url) |
394 | 407 | engine = create_engine( |
395 | 408 | RESOLVED_DATABASE_URL, |
396 | 409 | future=True, |
397 | | - connect_args=( |
398 | | - {"check_same_thread": False} |
399 | | - if RESOLVED_DATABASE_URL.startswith("sqlite:///") |
400 | | - else {} |
401 | | - ), |
| 410 | + connect_args=_sqlite_connect_args() if _is_sqlite_url(RESOLVED_DATABASE_URL) else {}, |
402 | 411 | ) |
403 | 412 | SessionLocal = sessionmaker(bind=engine, expire_on_commit=False, class_=Session) |
404 | 413 |
|
405 | 414 |
|
| 415 | +if _is_sqlite_url(RESOLVED_DATABASE_URL): |
| 416 | + |
| 417 | + @event.listens_for(engine, "connect") |
| 418 | + def _configure_sqlite_connection( |
| 419 | + dbapi_connection, |
| 420 | + connection_record, |
| 421 | + ): # pragma: no cover - event hook |
| 422 | + del connection_record |
| 423 | + if not isinstance(dbapi_connection, sqlite3.Connection): |
| 424 | + return |
| 425 | + cursor = dbapi_connection.cursor() |
| 426 | + try: |
| 427 | + cursor.execute("PRAGMA journal_mode=WAL;") |
| 428 | + cursor.execute("PRAGMA synchronous=NORMAL;") |
| 429 | + cursor.execute("PRAGMA busy_timeout=30000;") |
| 430 | + cursor.execute("PRAGMA foreign_keys=ON;") |
| 431 | + finally: |
| 432 | + cursor.close() |
| 433 | + |
| 434 | + |
406 | 435 | def init_db() -> None: |
407 | 436 | Base.metadata.create_all(bind=engine) |
408 | 437 |
|
|
0 commit comments