mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-11-10 15:50:24 +08:00
release/destroy 统一经 _close_handle 先清线程局部会话再 dispose,两步失败都 只记日志:单个插件的连接池故障不再让 close_database 跳过宿主同步与异步引擎的 释放,release_all_databases 也逐插件隔离。按模型建表对 __table__ 去重,单表 继承的父子类一并声明时不再对同一张表建两次。 卸载编排先删插件数据、后停插件,停机钩子里的 get_database() 会把刚销毁的库 重新建出来:注册表记下已销毁的插件标识,其后的 release 改为再次销毁并清除 标记,ensure 则撤销标记,宿主编排代码不动。PostgreSQL schema 名在归一改写过 标识或超长时追加插件标识哈希并截到 63 字节,My-Plugin、My_Plugin 与 my_plugin 不再折叠到同一个 schema 而在卸载时互相 DROP。 start 的失败分支释放已经建立、却进不了运行态的句柄,整体停止把只登记在 _classes 里的插件一并释放。声明的迁移目录不存在时在建句柄之前抛 FileNotFoundError,不再留下空库;SQLite 迁移 URL 改由引擎渲染; _get_sqlite_engine 的连接参数下沉到实际使用它的异步分支。
41 lines
1.5 KiB
Python
41 lines
1.5 KiB
Python
"""插件自有库的 Alembic 迁移执行。"""
|
||
|
||
from __future__ import annotations
|
||
|
||
from configparser import ConfigParser
|
||
from pathlib import Path
|
||
|
||
from alembic.command import upgrade
|
||
from alembic.config import Config
|
||
|
||
from app.db.plugin.container import PluginDatabaseHandle
|
||
|
||
__all__ = ["run_migrations"]
|
||
|
||
|
||
def run_migrations(handle: PluginDatabaseHandle, directory: Path) -> None:
|
||
"""
|
||
在句柄对应的库上把 Alembic 迁移跑到 head。
|
||
|
||
SQLite 按库文件 URL 起独立连接;PostgreSQL 复用句柄已被 ``schema_translate_map``
|
||
限定过的连接,迁移脚本的 env.py 必须从 ``context.config.attributes["connection"]``
|
||
取用它,否则迁移会落在 public schema 而不是该插件的 schema。
|
||
:param handle: 插件数据库句柄
|
||
:param directory: 迁移脚本目录,须符合 Alembic script_location 布局
|
||
"""
|
||
config = Config()
|
||
# 关闭 ini 插值:迁移目录里出现的 % 不应被当成插值语法(与宿主 _build_alembic_config 一致)
|
||
config.file_config = ConfigParser(interpolation=None)
|
||
config.set_main_option("script_location", str(directory))
|
||
if handle.owns_engine:
|
||
config.set_main_option(
|
||
"sqlalchemy.url",
|
||
handle.engine.url.render_as_string(hide_password=False),
|
||
)
|
||
upgrade(config, "head")
|
||
return
|
||
with handle.engine.connect() as connection:
|
||
config.attributes["connection"] = connection
|
||
upgrade(config, "head")
|
||
connection.commit()
|