mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-03-20 03:57:30 +08:00
feat(db): add support for SQLite WAL mode
This commit is contained in:
@@ -1,22 +1,25 @@
|
||||
from typing import Any, Generator, List, Optional, Self, Tuple
|
||||
|
||||
from sqlalchemy import NullPool, QueuePool, and_, create_engine, inspect
|
||||
from sqlalchemy import NullPool, QueuePool, and_, create_engine, inspect, text
|
||||
from sqlalchemy.orm import Session, as_declarative, declared_attr, scoped_session, sessionmaker
|
||||
|
||||
from app.core.config import settings
|
||||
|
||||
# 根据池类型设置 poolclass 和相关参数
|
||||
pool_class = NullPool if settings.DB_POOL_TYPE == "NullPool" else QueuePool
|
||||
connect_args = {
|
||||
"timeout": settings.DB_TIMEOUT
|
||||
}
|
||||
# 启用 WAL 模式时的额外配置
|
||||
if settings.DB_WAL_ENABLE:
|
||||
connect_args["check_same_thread"] = False
|
||||
kwargs = {
|
||||
"url": f"sqlite:///{settings.CONFIG_PATH}/user.db",
|
||||
"pool_pre_ping": settings.DB_POOL_PRE_PING,
|
||||
"echo": settings.DB_ECHO,
|
||||
"poolclass": pool_class,
|
||||
"pool_recycle": settings.DB_POOL_RECYCLE,
|
||||
"connect_args": {
|
||||
# "check_same_thread": False,
|
||||
"timeout": settings.DB_TIMEOUT
|
||||
}
|
||||
"connect_args": connect_args
|
||||
}
|
||||
# 当使用 QueuePool 时,添加 QueuePool 特有的参数
|
||||
if pool_class == QueuePool:
|
||||
@@ -27,6 +30,11 @@ if pool_class == QueuePool:
|
||||
})
|
||||
# 创建数据库引擎
|
||||
Engine = create_engine(**kwargs)
|
||||
# 根据配置设置日志模式
|
||||
journal_mode = "WAL" if settings.DB_WAL_ENABLE else "DELETE"
|
||||
with Engine.connect() as connection:
|
||||
current_mode = connection.execute(text(f"PRAGMA journal_mode={journal_mode};")).scalar()
|
||||
print(f"Database journal mode set to: {current_mode}")
|
||||
|
||||
# 会话工厂
|
||||
SessionFactory = sessionmaker(bind=Engine)
|
||||
@@ -49,11 +57,34 @@ def get_db() -> Generator:
|
||||
db.close()
|
||||
|
||||
|
||||
def perform_checkpoint(mode: str = "PASSIVE"):
|
||||
"""
|
||||
执行 SQLite 的 checkpoint 操作,将 WAL 文件内容写回主数据库
|
||||
:param mode: checkpoint 模式,可选值包括 "PASSIVE"、"FULL"、"RESTART"、"TRUNCATE"
|
||||
默认为 "PASSIVE",即不锁定 WAL 文件的轻量级同步
|
||||
"""
|
||||
if not settings.DB_WAL_ENABLE:
|
||||
return
|
||||
valid_modes = {"PASSIVE", "FULL", "RESTART", "TRUNCATE"}
|
||||
if mode.upper() not in valid_modes:
|
||||
raise ValueError(f"Invalid checkpoint mode '{mode}'. Must be one of {valid_modes}")
|
||||
try:
|
||||
# 使用指定的 checkpoint 模式,确保 WAL 文件数据被正确写回主数据库
|
||||
with Engine.connect() as conn:
|
||||
conn.execute(text(f"PRAGMA wal_checkpoint({mode.upper()});"))
|
||||
except Exception as e:
|
||||
print(f"Error during WAL checkpoint: {e}")
|
||||
|
||||
|
||||
def close_database():
|
||||
"""
|
||||
关闭所有数据库连接
|
||||
关闭所有数据库连接并清理资源
|
||||
"""
|
||||
Engine.dispose()
|
||||
try:
|
||||
# 释放连接池,SQLite 会自动清空 WAL 文件,这里不单独再调用 checkpoint
|
||||
Engine.dispose()
|
||||
except Exception as e:
|
||||
print(f"Error while disposing database connections: {e}")
|
||||
|
||||
|
||||
def get_args_db(args: tuple, kwargs: dict) -> Optional[Session]:
|
||||
|
||||
Reference in New Issue
Block a user