init
This commit is contained in:
73
backend/core/db.py
Normal file
73
backend/core/db.py
Normal file
@@ -0,0 +1,73 @@
|
||||
"""
|
||||
Shared SQLAlchemy engine / session + schema bootstrap
|
||||
"""
|
||||
from __future__ import annotations
|
||||
import importlib, datetime
|
||||
import os
|
||||
|
||||
from sqlalchemy import (
|
||||
create_engine, event, Table, Column, Text, DateTime, Index, make_url
|
||||
)
|
||||
from sqlalchemy.engine import url
|
||||
from sqlalchemy.orm import sessionmaker, registry
|
||||
from backend.core.settings import (
|
||||
SQLALCHEMY_DATABASE_URI, DB_POOL_SIZE, DB_ECHO, SKIP_SCHEMA_BOOTSTRAP
|
||||
)
|
||||
|
||||
IS_PG = SQLALCHEMY_DATABASE_URI.startswith("postgresql")
|
||||
|
||||
parsed_url = make_url(SQLALCHEMY_DATABASE_URI) # string into URL object
|
||||
|
||||
# engine & session
|
||||
connect_args = {"sslmode": "require"} if parsed_url.drivername.startswith("postgresql") else {}
|
||||
engine = create_engine(
|
||||
SQLALCHEMY_DATABASE_URI,
|
||||
pool_size = DB_POOL_SIZE,
|
||||
max_overflow = 20,
|
||||
pool_timeout = 30,
|
||||
echo = DB_ECHO,
|
||||
future = True,
|
||||
pool_pre_ping = True,
|
||||
pool_recycle=3600,
|
||||
connect_args = connect_args
|
||||
)
|
||||
|
||||
# SQLite -> WAL for concurrency
|
||||
if SQLALCHEMY_DATABASE_URI.startswith("sqlite:///"):
|
||||
|
||||
@event.listens_for(engine, "connect")
|
||||
def _set_wal(dbapi_conn, _):
|
||||
dbapi_conn.execute("PRAGMA journal_mode=WAL;")
|
||||
|
||||
SessionLocal = sessionmaker(bind=engine, autoflush=False,
|
||||
expire_on_commit=False, future=True)
|
||||
|
||||
# metadata (tables from every module)
|
||||
mapper_registry = registry()
|
||||
metadata = mapper_registry.metadata
|
||||
|
||||
# download-cache table
|
||||
download_cache = Table(
|
||||
"download_cache", metadata,
|
||||
Column("key", Text, primary_key=True),
|
||||
Column("path", Text, nullable=False),
|
||||
Column("ext", Text, nullable=False),
|
||||
Column("created_at", DateTime, default=datetime.datetime.utcnow,
|
||||
nullable=False, index=True),
|
||||
)
|
||||
Index("ix_download_cache_created", download_cache.c.created_at)
|
||||
|
||||
# auto-bootstrap all
|
||||
def _bootstrap_schema() -> None:
|
||||
"""Import modules then create."""
|
||||
table_modules = (
|
||||
"backend.core.db_xp",
|
||||
"backend.web.db_extra",
|
||||
"backend.core.formats",
|
||||
)
|
||||
for mod in table_modules:
|
||||
importlib.import_module(mod)
|
||||
|
||||
metadata.create_all(engine)
|
||||
if SKIP_SCHEMA_BOOTSTRAP != "1":
|
||||
_bootstrap_schema()
|
||||
Reference in New Issue
Block a user