fix(plugin_system): 修复无配置插件加载时产生不必要警告
对于未定义 `config_schema` 的插件,现在会将其视作一种正常情况,并为其分配一个空的配置。 此举修复了先前版本中,这类插件在加载时会错误地触发“配置文件不存在”警告的问题。同时将生成默认配置文件的日志等级从 debug 调整为 info,使其在默认情况下可见。
This commit is contained in:
committed by
Windpicker-owo
parent
d3f88ce981
commit
83eb5c80c5
@@ -1,7 +1,8 @@
|
|||||||
# mmc/src/common/database/db_migration.py
|
# mmc/src/common/database/db_migration.py
|
||||||
|
|
||||||
from sqlalchemy import inspect
|
from sqlalchemy import inspect
|
||||||
from sqlalchemy.schema import AddColumn, CreateIndex
|
from sqlalchemy.schema import CreateIndex
|
||||||
|
from sqlalchemy.sql import text
|
||||||
|
|
||||||
from src.common.database.sqlalchemy_models import Base, get_engine
|
from src.common.database.sqlalchemy_models import Base, get_engine
|
||||||
from src.common.logger import get_logger
|
from src.common.logger import get_logger
|
||||||
@@ -17,7 +18,7 @@ async def check_and_migrate_database():
|
|||||||
- 自动为现有表创建缺失的索引。
|
- 自动为现有表创建缺失的索引。
|
||||||
"""
|
"""
|
||||||
logger.info("正在检查数据库结构并执行自动迁移...")
|
logger.info("正在检查数据库结构并执行自动迁移...")
|
||||||
engine = await get_engine()
|
engine = get_engine()
|
||||||
|
|
||||||
async with engine.connect() as connection:
|
async with engine.connect() as connection:
|
||||||
# 在同步上下文中运行inspector操作
|
# 在同步上下文中运行inspector操作
|
||||||
@@ -66,20 +67,34 @@ async def check_and_migrate_database():
|
|||||||
|
|
||||||
if missing_columns:
|
if missing_columns:
|
||||||
logger.info(f"在表 '{table_name}' 中发现缺失的列: {', '.join(missing_columns)}")
|
logger.info(f"在表 '{table_name}' 中发现缺失的列: {', '.join(missing_columns)}")
|
||||||
async with connection.begin() as trans:
|
|
||||||
|
def add_columns_sync(conn):
|
||||||
|
dialect = conn.dialect
|
||||||
for column_name in missing_columns:
|
for column_name in missing_columns:
|
||||||
try:
|
|
||||||
column = table.c[column_name]
|
column = table.c[column_name]
|
||||||
add_column_ddl = AddColumn(table_name, column)
|
|
||||||
await connection.execute(add_column_ddl)
|
# 使用DDLCompiler为特定方言编译列
|
||||||
|
compiler = dialect.ddl_compiler(dialect, None)
|
||||||
|
|
||||||
|
# 编译列的数据类型
|
||||||
|
column_type = compiler.get_column_specification(column)
|
||||||
|
|
||||||
|
# 构建原生SQL
|
||||||
|
sql = f"ALTER TABLE {table.name} ADD COLUMN {column.name} {column_type}"
|
||||||
|
|
||||||
|
# 添加默认值(如果存在)
|
||||||
|
if column.default:
|
||||||
|
default_value = compiler.render_literal_value(column.default.arg, column.type)
|
||||||
|
sql += f" DEFAULT {default_value}"
|
||||||
|
|
||||||
|
# 添加非空约束(如果存在)
|
||||||
|
if not column.nullable:
|
||||||
|
sql += " NOT NULL"
|
||||||
|
|
||||||
|
conn.execute(text(sql))
|
||||||
logger.info(f"成功向表 '{table_name}' 添加列 '{column_name}'。")
|
logger.info(f"成功向表 '{table_name}' 添加列 '{column_name}'。")
|
||||||
except Exception as e:
|
|
||||||
logger.error(
|
await connection.run_sync(add_columns_sync)
|
||||||
f"向表 '{table_name}' 添加列 '{column_name}' 失败: {e}",
|
|
||||||
exc_info=True,
|
|
||||||
)
|
|
||||||
await trans.rollback()
|
|
||||||
break # 如果一列失败,则停止处理此表的其他列
|
|
||||||
else:
|
else:
|
||||||
logger.info(f"表 '{table_name}' 的列结构一致。")
|
logger.info(f"表 '{table_name}' 的列结构一致。")
|
||||||
|
|
||||||
@@ -92,20 +107,16 @@ async def check_and_migrate_database():
|
|||||||
|
|
||||||
if missing_indexes:
|
if missing_indexes:
|
||||||
logger.info(f"在表 '{table_name}' 中发现缺失的索引: {', '.join(missing_indexes)}")
|
logger.info(f"在表 '{table_name}' 中发现缺失的索引: {', '.join(missing_indexes)}")
|
||||||
async with connection.begin() as trans:
|
|
||||||
|
def add_indexes_sync(conn):
|
||||||
|
with conn.begin():
|
||||||
for index_name in missing_indexes:
|
for index_name in missing_indexes:
|
||||||
try:
|
|
||||||
index_obj = next((idx for idx in table.indexes if idx.name == index_name), None)
|
index_obj = next((idx for idx in table.indexes if idx.name == index_name), None)
|
||||||
if index_obj is not None:
|
if index_obj is not None:
|
||||||
await connection.execute(CreateIndex(index_obj))
|
conn.execute(CreateIndex(index_obj))
|
||||||
logger.info(f"成功为表 '{table_name}' 创建索引 '{index_name}'。")
|
logger.info(f"成功为表 '{table_name}' 创建索引 '{index_name}'。")
|
||||||
except Exception as e:
|
|
||||||
logger.error(
|
await connection.run_sync(add_indexes_sync)
|
||||||
f"为表 '{table_name}' 创建索引 '{index_name}' 失败: {e}",
|
|
||||||
exc_info=True,
|
|
||||||
)
|
|
||||||
await trans.rollback()
|
|
||||||
break # 如果一个索引失败,则停止处理此表的其他索引
|
|
||||||
else:
|
else:
|
||||||
logger.debug(f"表 '{table_name}' 的索引一致。")
|
logger.debug(f"表 '{table_name}' 的索引一致。")
|
||||||
|
|
||||||
@@ -114,3 +125,4 @@ async def check_and_migrate_database():
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
logger.info("数据库结构检查与自动迁移完成。")
|
logger.info("数据库结构检查与自动迁移完成。")
|
||||||
|
|
||||||
|
|||||||
@@ -215,7 +215,7 @@ class PluginBase(ABC):
|
|||||||
def _generate_and_save_default_config(self, config_file_path: str):
|
def _generate_and_save_default_config(self, config_file_path: str):
|
||||||
"""根据插件的Schema生成并保存默认配置文件"""
|
"""根据插件的Schema生成并保存默认配置文件"""
|
||||||
if not self.config_schema:
|
if not self.config_schema:
|
||||||
logger.debug(f"{self.log_prefix} 插件未定义config_schema,不生成配置文件")
|
logger.info(f"{self.log_prefix} 插件未定义config_schema,不生成配置文件")
|
||||||
return
|
return
|
||||||
|
|
||||||
toml_str = f"# {self.plugin_name} - 自动生成的配置文件\n"
|
toml_str = f"# {self.plugin_name} - 自动生成的配置文件\n"
|
||||||
@@ -479,6 +479,12 @@ class PluginBase(ABC):
|
|||||||
|
|
||||||
# 检查最终的用户配置文件是否存在
|
# 检查最终的用户配置文件是否存在
|
||||||
if not os.path.exists(user_config_path):
|
if not os.path.exists(user_config_path):
|
||||||
|
# 如果插件没有定义config_schema,那么不创建文件是正常行为
|
||||||
|
if not self.config_schema:
|
||||||
|
logger.debug(f"{self.log_prefix} 插件未定义config_schema,使用空的配置.")
|
||||||
|
self.config = {}
|
||||||
|
return
|
||||||
|
|
||||||
logger.warning(f"{self.log_prefix} 用户配置文件 {user_config_path} 不存在且无法创建。")
|
logger.warning(f"{self.log_prefix} 用户配置文件 {user_config_path} 不存在且无法创建。")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user