mirror of
https://github.com/zhenxun-org/zhenxun_bot.git
synced 2026-10-08 21:30:01 +08:00
🐛 fix(db): 优化多数据库脚本兼容性与初始化错误处理 (#2095)
* 🐛 fix(db): 优化多数据库脚本兼容性与初始化错误处理 - 为 `BotConsole`、`GroupConsole` 和 `GroupInfo` 模型增加针对 PostgreSQL 和 MySQL 的字段类型转换脚本 - 统一将插件和任务相关的禁用/可用字段类型修改为 `TEXT` - 优化数据库初始化逻辑,增加对 `OperationalError` 的细粒度处理,忽略常见的重复执行错误 - 简化 `db_context` 内部配置解析逻辑 * 🚨 auto fix by pre-commit hooks --------- Co-authored-by: webjoin111 <455457521@qq.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: HibiKier <45528451+HibiKier@users.noreply.github.com>
This commit is contained in:
co-authored by
webjoin111
pre-commit-ci[bot]
HibiKier
parent
4f152638b0
commit
b95acce800
@@ -2,6 +2,7 @@ from typing import Literal, overload
|
|||||||
|
|
||||||
from tortoise import fields
|
from tortoise import fields
|
||||||
|
|
||||||
|
from zhenxun.configs.config import BotConfig
|
||||||
from zhenxun.services.cache.runtime_cache import BotMemoryCache
|
from zhenxun.services.cache.runtime_cache import BotMemoryCache
|
||||||
from zhenxun.services.db_context import Model
|
from zhenxun.services.db_context import Model
|
||||||
from zhenxun.utils.enum import CacheType
|
from zhenxun.utils.enum import CacheType
|
||||||
@@ -469,9 +470,32 @@ class BotConsole(Model):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def _run_script(cls):
|
async def _run_script(cls):
|
||||||
return [
|
db_type = (BotConfig.get_sql_type() or "").lower()
|
||||||
|
|
||||||
|
scripts = [
|
||||||
"ALTER TABLE bot_console RENAME COLUMN block_plugin TO block_plugins;",
|
"ALTER TABLE bot_console RENAME COLUMN block_plugin TO block_plugins;",
|
||||||
"ALTER TABLE bot_console RENAME COLUMN block_task TO block_tasks;",
|
"ALTER TABLE bot_console RENAME COLUMN block_task TO block_tasks;",
|
||||||
"ALTER TABLE bot_console ADD available_plugins text default '';",
|
"ALTER TABLE bot_console ADD available_plugins text default '';",
|
||||||
"ALTER TABLE bot_console ADD available_tasks text default '';",
|
"ALTER TABLE bot_console ADD available_tasks text default '';",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
if "postgres" in db_type:
|
||||||
|
scripts.extend(
|
||||||
|
[
|
||||||
|
"ALTER TABLE bot_console ALTER COLUMN block_plugins TYPE TEXT;",
|
||||||
|
"ALTER TABLE bot_console ALTER COLUMN block_tasks TYPE TEXT;",
|
||||||
|
"ALTER TABLE bot_console ALTER COLUMN available_plugins TYPE TEXT;",
|
||||||
|
"ALTER TABLE bot_console ALTER COLUMN available_tasks TYPE TEXT;",
|
||||||
|
]
|
||||||
|
)
|
||||||
|
elif "mysql" in db_type:
|
||||||
|
scripts.extend(
|
||||||
|
[
|
||||||
|
"ALTER TABLE bot_console MODIFY COLUMN block_plugins TEXT;",
|
||||||
|
"ALTER TABLE bot_console MODIFY COLUMN block_tasks TEXT;",
|
||||||
|
"ALTER TABLE bot_console MODIFY COLUMN available_plugins TEXT;",
|
||||||
|
"ALTER TABLE bot_console MODIFY COLUMN available_tasks TEXT;",
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
return scripts
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ from typing_extensions import Self
|
|||||||
from tortoise import fields
|
from tortoise import fields
|
||||||
from tortoise.backends.base.client import BaseDBAsyncClient
|
from tortoise.backends.base.client import BaseDBAsyncClient
|
||||||
|
|
||||||
|
from zhenxun.configs.config import BotConfig
|
||||||
from zhenxun.models.plugin_info import PluginInfo
|
from zhenxun.models.plugin_info import PluginInfo
|
||||||
from zhenxun.models.task_info import TaskInfo
|
from zhenxun.models.task_info import TaskInfo
|
||||||
from zhenxun.services.cache import CacheRoot
|
from zhenxun.services.cache import CacheRoot
|
||||||
@@ -514,11 +515,52 @@ class GroupConsole(Model):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _run_script(cls):
|
def _run_script(cls):
|
||||||
return [
|
db_type = (BotConfig.get_sql_type() or "").lower()
|
||||||
|
|
||||||
|
scripts = [
|
||||||
"ALTER TABLE group_console ADD superuser_block_plugin"
|
"ALTER TABLE group_console ADD superuser_block_plugin"
|
||||||
" character varying(255) NOT NULL DEFAULT '';",
|
" Text NOT NULL DEFAULT '';",
|
||||||
"ALTER TABLE group_console ADD superuser_block_task"
|
"ALTER TABLE group_console ADD superuser_block_task"
|
||||||
" character varying(255) NOT NULL DEFAULT '';",
|
" Text NOT NULL DEFAULT '';",
|
||||||
"CREATE INDEX idx_group_console_group_id ON group_console(group_id);",
|
"CREATE INDEX idx_group_console_group_id ON group_console(group_id);",
|
||||||
"CREATE INDEX idx_group_console_group_null_channel ON group_console(group_id) WHERE channel_id IS NULL;", # 单独创建channel为空的索引 # noqa: E501
|
(
|
||||||
|
"CREATE INDEX idx_group_console_group_null_channel ON "
|
||||||
|
"group_console(group_id) WHERE channel_id IS NULL;"
|
||||||
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
if "postgres" in db_type:
|
||||||
|
scripts.extend(
|
||||||
|
[
|
||||||
|
(
|
||||||
|
"ALTER TABLE group_console ALTER COLUMN "
|
||||||
|
"block_plugin TYPE TEXT;"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"ALTER TABLE group_console ALTER COLUMN "
|
||||||
|
"superuser_block_plugin TYPE TEXT;"
|
||||||
|
),
|
||||||
|
("ALTER TABLE group_console ALTER COLUMN " "block_task TYPE TEXT;"),
|
||||||
|
(
|
||||||
|
"ALTER TABLE group_console ALTER COLUMN "
|
||||||
|
"superuser_block_task TYPE TEXT;"
|
||||||
|
),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
elif "mysql" in db_type:
|
||||||
|
scripts.extend(
|
||||||
|
[
|
||||||
|
("ALTER TABLE group_console MODIFY COLUMN " "block_plugin TEXT;"),
|
||||||
|
(
|
||||||
|
"ALTER TABLE group_console MODIFY COLUMN "
|
||||||
|
"superuser_block_plugin TEXT;"
|
||||||
|
),
|
||||||
|
("ALTER TABLE group_console MODIFY COLUMN " "block_task TEXT;"),
|
||||||
|
(
|
||||||
|
"ALTER TABLE group_console MODIFY COLUMN "
|
||||||
|
"superuser_block_task TEXT;"
|
||||||
|
),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
return scripts
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
from tortoise import fields
|
from tortoise import fields
|
||||||
|
|
||||||
|
from zhenxun.configs.config import BotConfig
|
||||||
from zhenxun.services.db_context import Model
|
from zhenxun.services.db_context import Model
|
||||||
|
|
||||||
|
|
||||||
@@ -109,7 +110,9 @@ class GroupInfo(Model):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _run_script(cls):
|
def _run_script(cls):
|
||||||
return [
|
db_type = (BotConfig.get_sql_type() or "").lower()
|
||||||
|
|
||||||
|
scripts = [
|
||||||
"ALTER TABLE group_info ADD group_flag Integer NOT NULL DEFAULT 0;",
|
"ALTER TABLE group_info ADD group_flag Integer NOT NULL DEFAULT 0;",
|
||||||
# group_info表添加一个group_flag
|
# group_info表添加一个group_flag
|
||||||
"ALTER TABLE group_info ALTER COLUMN group_id TYPE character varying(255);",
|
"ALTER TABLE group_info ALTER COLUMN group_id TYPE character varying(255);",
|
||||||
@@ -118,3 +121,20 @@ class GroupInfo(Model):
|
|||||||
"ALTER TABLE group_info ADD platform character varying(255) NOT NULL"
|
"ALTER TABLE group_info ADD platform character varying(255) NOT NULL"
|
||||||
" DEFAULT 'qq';",
|
" DEFAULT 'qq';",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
if "postgres" in db_type:
|
||||||
|
scripts.extend(
|
||||||
|
[
|
||||||
|
"ALTER TABLE group_info ALTER COLUMN block_plugin TYPE TEXT;",
|
||||||
|
"ALTER TABLE group_info ALTER COLUMN block_task TYPE TEXT;",
|
||||||
|
]
|
||||||
|
)
|
||||||
|
elif "mysql" in db_type:
|
||||||
|
scripts.extend(
|
||||||
|
[
|
||||||
|
"ALTER TABLE group_info MODIFY COLUMN block_plugin TEXT;",
|
||||||
|
"ALTER TABLE group_info MODIFY COLUMN block_task TEXT;",
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
return scripts
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import nonebot
|
|||||||
from nonebot.utils import is_coroutine_callable
|
from nonebot.utils import is_coroutine_callable
|
||||||
from tortoise import Tortoise
|
from tortoise import Tortoise
|
||||||
from tortoise.connection import connections
|
from tortoise.connection import connections
|
||||||
|
from tortoise.exceptions import OperationalError
|
||||||
|
|
||||||
from zhenxun.configs.config import BotConfig
|
from zhenxun.configs.config import BotConfig
|
||||||
from zhenxun.services.log import logger
|
from zhenxun.services.log import logger
|
||||||
@@ -50,11 +51,8 @@ def get_config() -> dict:
|
|||||||
raise DbUrlIsNode("数据库Url连接字符串为空,请检查配置文件(.env.dev)")
|
raise DbUrlIsNode("数据库Url连接字符串为空,请检查配置文件(.env.dev)")
|
||||||
parsed = urlparse(BotConfig.db_url)
|
parsed = urlparse(BotConfig.db_url)
|
||||||
|
|
||||||
# 基础配置
|
|
||||||
config = {
|
config = {
|
||||||
"connections": {
|
"connections": {"default": BotConfig.db_url},
|
||||||
"default": BotConfig.db_url # 默认直接使用连接字符串
|
|
||||||
},
|
|
||||||
"apps": {
|
"apps": {
|
||||||
"models": {
|
"models": {
|
||||||
"models": db_model.models,
|
"models": db_model.models,
|
||||||
@@ -64,7 +62,6 @@ def get_config() -> dict:
|
|||||||
"timezone": "Asia/Shanghai",
|
"timezone": "Asia/Shanghai",
|
||||||
}
|
}
|
||||||
|
|
||||||
# 根据数据库类型应用高级配置
|
|
||||||
if parsed.scheme.startswith("postgres"):
|
if parsed.scheme.startswith("postgres"):
|
||||||
config["connections"]["default"] = {
|
config["connections"]["default"] = {
|
||||||
"engine": "tortoise.backends.asyncpg",
|
"engine": "tortoise.backends.asyncpg",
|
||||||
@@ -143,7 +140,24 @@ async def init():
|
|||||||
await asyncio.wait_for(
|
await asyncio.wait_for(
|
||||||
db.execute_query_dict(sql), timeout=DB_TIMEOUT_SECONDS
|
db.execute_query_dict(sql), timeout=DB_TIMEOUT_SECONDS
|
||||||
)
|
)
|
||||||
# await TestSQL.raw(sql)
|
except OperationalError as e:
|
||||||
|
err_str = str(e).lower()
|
||||||
|
if any(
|
||||||
|
x in err_str
|
||||||
|
for x in [
|
||||||
|
"already exists",
|
||||||
|
"duplicate column",
|
||||||
|
"已经存在",
|
||||||
|
"已存在",
|
||||||
|
]
|
||||||
|
):
|
||||||
|
pass
|
||||||
|
elif any(
|
||||||
|
x in err_str for x in ["does not exist", "check that", "不存在"]
|
||||||
|
) and ("drop" in sql.lower() or "rename" in sql.lower()):
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
logger.warning(f"执行SQL警告: {sql} || {e}")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.debug(f"执行SQL: {sql} 错误...", e=e)
|
logger.debug(f"执行SQL: {sql} 错误...", e=e)
|
||||||
if sql_list:
|
if sql_list:
|
||||||
|
|||||||
Reference in New Issue
Block a user