feat(database): add managed backup and offline restore (#6359)

This commit is contained in:
InfinityPacer
2026-08-19 17:34:32 +08:00
committed by GitHub
parent f4a879b3de
commit f700db5ac8
27 changed files with 1576 additions and 80 deletions
+61
View File
@@ -0,0 +1,61 @@
"""数据库治理能力的宿主组合根。"""
from __future__ import annotations
from app.adapters.system.backup.database import (
PostgreSQLBackupBackend,
SQLiteBackupBackend,
)
from app.application.backup import BackupPolicy, DatabaseBackupService
from app.application.database import (
DatabaseGovernance,
DatabaseHealthService,
configure_database_governance,
)
from app.application.maintenance import (
DataCleanupService,
read_cleanup_policy,
)
from app.db.engine import get_engine
from app.db.health import probe_database
from app.db.maintenance import DatabaseCleanupRepository
from app.db.session import SessionFactory
from app.runtime.config import settings
def build_database_governance() -> DatabaseGovernance:
"""以缓存同步引擎为事实源构造一个完整数据库治理门面。"""
engine = get_engine()
dialect = engine.dialect.name
if dialect == "sqlite":
backup_backend = SQLiteBackupBackend(engine)
elif dialect == "postgresql":
backup_backend = PostgreSQLBackupBackend(engine)
else:
raise RuntimeError(f"不支持的数据库类型:{dialect}")
return DatabaseGovernance(
health=DatabaseHealthService(probe_database),
cleanup=DataCleanupService(
repository=DatabaseCleanupRepository(session_factory=SessionFactory),
policy_reader=read_cleanup_policy,
),
backup=DatabaseBackupService(
backend=backup_backend,
policy_reader=read_backup_policy,
),
)
def configure_database() -> None:
"""构造并登记宿主进程唯一的数据库治理门面。"""
configure_database_governance(build_database_governance())
def read_backup_policy() -> BackupPolicy:
"""读取一次可热更新的数据库备份目录与保留策略。"""
return BackupPolicy(
root=settings.DATABASE_BACKUP_PATH,
retention_days=settings.DB_BACKUP_RETENTION_DAYS,
max_count=settings.DB_BACKUP_MAX_COUNT,
)
+4 -18
View File
@@ -36,7 +36,7 @@ from app.application.messaging.message import (
stop_message,
)
from app.application.configuration import SystemConfigService, configure_system_config
from app.application.database import DatabaseHealthService, configure_database_health
from app.application.database import configure_database_governance
from app.application.service import configure_service_directory
from app.application.plugin.runtime import configure_plugin_runtime
from app.application.module import configure_module_runtime
@@ -55,19 +55,13 @@ from app.application.workflow import WorkflowQueryService, configure_workflow_qu
from app.application.agentdata import configure_agent_data_ports
from app.api.data import configure_api_data_ports
from app.application.subscription.write import configure_subscribe_writer
from app.application.maintenance import (
DataCleanupService,
configure_cleanup_service_factory,
read_cleanup_policy,
)
from app.adapters.external.server import (
MoviePilotServerHelper,
configure_server_application_services,
)
from app.application.server.report import ServerReportService
from app.application.server.share import ServerSharingService
from app.db import close_database
from app.db.session import get_async_db, get_db
from app.db.session import close_database, get_async_db, get_db
from app.db.uow import SqlAlchemyAsyncUnitOfWork, SqlAlchemyUnitOfWork
from app.db.oper.subscribe import SubscribeOper
from app.db.oper.agentchat import AgentChatOper
@@ -84,9 +78,6 @@ from app.db.oper.site import SiteOper
from app.db.oper.message import MessageOper
from app.db.oper.subscribehistory import SubscribeHistoryOper
from app.db.oper.plugindata import PluginDataOper
from app.db.maintenance import DatabaseCleanupRepository
from app.db.session import SessionFactory
from app.db.health import probe_database
from app.db.oper.systemconfig import SystemConfigOper
from app.db.oper.workflow import WorkflowOper
from app.command import CommandChain
@@ -94,6 +85,7 @@ from app.schemas.message import Message
from app.schemas.message import MessageType
from app.schemas.types import SystemConfigKey
from app.startup.agent_initializer import init_agent, stop_agent
from app.startup.database import build_database_governance
from app.startup.managed_resources_initializer import (
init_managed_resources,
stop_managed_resources,
@@ -441,7 +433,7 @@ async def init_modules():
user=lambda: UserOper(),
)
configure_system_config(SystemConfigService(repository=SystemConfigOper()))
configure_database_health(DatabaseHealthService(probe_database))
configure_database_governance(build_database_governance())
configure_agent_chat_service(AgentChatService(repository=AgentChatOper()))
configure_user_lookups(
by_id=lambda user_id: UserOper().get_by_id(user_id),
@@ -474,12 +466,6 @@ async def init_modules():
plugin_data=lambda: PluginDataOper(),
)
configure_subscribe_writer(lambda: SubscribeOper())
configure_cleanup_service_factory(
lambda: DataCleanupService(
repository=DatabaseCleanupRepository(session_factory=SessionFactory),
policy_reader=read_cleanup_policy,
)
)
# 托管资源只在这里装配声明与 adapter,具体资源仍由首个消费者显式激活。
init_managed_resources()
# 应用服务不反向依赖 Chain,由启动组合层注入壁纸来源。