- Add DatabaseMigrationManager for orchestrating database migrations, including planning and executing migration steps. - Introduce models for migration state, execution context, and migration steps. - Implement MigrationPlanner to generate migration plans based on current and target versions. - Create MigrationRegistry for registering and managing migration steps. - Develop SchemaVersionResolver to determine the current database schema version. - Add SQLiteSchemaInspector for inspecting SQLite database structures. - Implement progress reporting tools using rich for visualizing migration progress. - Introduce SQLiteUserVersionStore for managing schema version storage in SQLite.
160 lines
5.0 KiB
Python
160 lines
5.0 KiB
Python
"""数据库迁移内置版本与默认注册表。"""
|
|
|
|
from typing import List, Optional
|
|
|
|
from .legacy_v1_to_v2 import migrate_legacy_v1_to_v2
|
|
from .models import DatabaseSchemaSnapshot, MigrationStep
|
|
from .registry import MigrationRegistry
|
|
from .resolver import BaseSchemaVersionDetector, SchemaVersionResolver
|
|
from .version_store import SQLiteUserVersionStore
|
|
from .schema import SQLiteSchemaInspector
|
|
|
|
EMPTY_SCHEMA_VERSION = 0
|
|
LEGACY_V1_SCHEMA_VERSION = 1
|
|
LATEST_SCHEMA_VERSION = 2
|
|
|
|
_LEGACY_V1_EXCLUSIVE_TABLES = (
|
|
"chat_streams",
|
|
"emoji",
|
|
"emoji_description_cache",
|
|
"expression",
|
|
"group_info",
|
|
"image_descriptions",
|
|
"jargon",
|
|
"messages",
|
|
"thinking_back",
|
|
)
|
|
|
|
|
|
class LatestSchemaVersionDetector(BaseSchemaVersionDetector):
|
|
"""当前最新 schema 结构探测器。"""
|
|
|
|
@property
|
|
def name(self) -> str:
|
|
"""返回探测器名称。
|
|
|
|
Returns:
|
|
str: 当前探测器名称。
|
|
"""
|
|
return "latest_schema_detector"
|
|
|
|
def detect_version(self, snapshot: DatabaseSchemaSnapshot) -> Optional[int]:
|
|
"""检测数据库是否已经是当前最新结构。
|
|
|
|
Args:
|
|
snapshot: 当前数据库结构快照。
|
|
|
|
Returns:
|
|
Optional[int]: 若识别为最新结构则返回最新版本号,否则返回 ``None``。
|
|
"""
|
|
if any(snapshot.has_table(table_name) for table_name in _LEGACY_V1_EXCLUSIVE_TABLES):
|
|
return None
|
|
|
|
latest_marker_tables = (
|
|
"mai_messages",
|
|
"chat_sessions",
|
|
"expressions",
|
|
"jargons",
|
|
"thinking_questions",
|
|
"tool_records",
|
|
)
|
|
if not all(snapshot.has_table(table_name) for table_name in latest_marker_tables):
|
|
return None
|
|
if not snapshot.has_column("images", "image_hash"):
|
|
return None
|
|
if not snapshot.has_column("images", "full_path"):
|
|
return None
|
|
if not snapshot.has_column("images", "image_type"):
|
|
return None
|
|
if not snapshot.has_column("action_records", "session_id"):
|
|
return None
|
|
if not snapshot.has_column("chat_history", "session_id"):
|
|
return None
|
|
if not snapshot.has_column("person_info", "user_nickname"):
|
|
return None
|
|
return LATEST_SCHEMA_VERSION
|
|
|
|
|
|
class LegacyV1SchemaDetector(BaseSchemaVersionDetector):
|
|
"""旧版 ``0.x`` schema 结构探测器。"""
|
|
|
|
@property
|
|
def name(self) -> str:
|
|
"""返回探测器名称。
|
|
|
|
Returns:
|
|
str: 当前探测器名称。
|
|
"""
|
|
return "legacy_v1_schema_detector"
|
|
|
|
def detect_version(self, snapshot: DatabaseSchemaSnapshot) -> Optional[int]:
|
|
"""检测数据库是否为旧版 ``0.x`` 结构。
|
|
|
|
Args:
|
|
snapshot: 当前数据库结构快照。
|
|
|
|
Returns:
|
|
Optional[int]: 若识别为旧版结构则返回 ``1``,否则返回 ``None``。
|
|
"""
|
|
if any(snapshot.has_table(table_name) for table_name in _LEGACY_V1_EXCLUSIVE_TABLES):
|
|
return LEGACY_V1_SCHEMA_VERSION
|
|
|
|
legacy_shared_markers = (
|
|
("action_records", ("chat_id", "time")),
|
|
("chat_history", ("chat_id", "original_text")),
|
|
("images", ("emoji_hash", "path", "type")),
|
|
("llm_usage", ("model_api_provider", "status")),
|
|
("online_time", ("duration",)),
|
|
("person_info", ("nickname", "group_nick_name")),
|
|
)
|
|
for table_name, required_columns in legacy_shared_markers:
|
|
if snapshot.has_table(table_name) and all(
|
|
snapshot.has_column(table_name, column_name) for column_name in required_columns
|
|
):
|
|
return LEGACY_V1_SCHEMA_VERSION
|
|
return None
|
|
|
|
|
|
def build_default_schema_version_detectors() -> List[BaseSchemaVersionDetector]:
|
|
"""构建默认 schema 版本探测器链。
|
|
|
|
Returns:
|
|
List[BaseSchemaVersionDetector]: 按优先级排序的探测器列表。
|
|
"""
|
|
return [
|
|
LatestSchemaVersionDetector(),
|
|
LegacyV1SchemaDetector(),
|
|
]
|
|
|
|
|
|
def build_default_schema_version_resolver() -> SchemaVersionResolver:
|
|
"""构建默认 schema 版本解析器。
|
|
|
|
Returns:
|
|
SchemaVersionResolver: 配置完成的 schema 版本解析器。
|
|
"""
|
|
return SchemaVersionResolver(
|
|
version_store=SQLiteUserVersionStore(),
|
|
schema_inspector=SQLiteSchemaInspector(),
|
|
detectors=build_default_schema_version_detectors(),
|
|
)
|
|
|
|
|
|
def build_default_migration_registry() -> MigrationRegistry:
|
|
"""构建默认迁移步骤注册表。
|
|
|
|
Returns:
|
|
MigrationRegistry: 含默认迁移步骤的注册表实例。
|
|
"""
|
|
return MigrationRegistry(
|
|
steps=[
|
|
MigrationStep(
|
|
version_from=LEGACY_V1_SCHEMA_VERSION,
|
|
version_to=LATEST_SCHEMA_VERSION,
|
|
name="legacy_v1_to_latest_v2",
|
|
description="将旧版 0.x 数据库整体迁移到当前最新 schema。",
|
|
handler=migrate_legacy_v1_to_v2,
|
|
)
|
|
]
|
|
)
|