add: Plugin 基类支持 [workers.config.database] 配置接入 PostgreSQL(url 优先,SQLite 回落)
This commit is contained in:
@@ -18,11 +18,11 @@ Plugin 基类 — 统一 Worker 插件初始化与清理生命周期
|
||||
|
||||
class MyPlugin(Plugin):
|
||||
type = "myname"
|
||||
db_name = "myname.db" # 自动在 data_dir 下建库;不需要则置 None
|
||||
db_name = "myname.db" # SQLite:自动在 data_dir 下建库;config 含 database.url 时优先走 PostgreSQL;不需要则置 None
|
||||
auto_bind = True # 首次初始化时自动 auto_bind_models("myname")
|
||||
|
||||
async def on_init(self):
|
||||
# 数据库已由基类 _bootstrap 初始化(self.db)
|
||||
# 数据库已由基类 _bootstrap 初始化(self.db,SQLite 或 PostgreSQL)
|
||||
self.set_var("db", self.db)
|
||||
# 需要后台任务时:
|
||||
# self.spawn_task(self._background_loop())
|
||||
@@ -31,6 +31,15 @@ Plugin 基类 — 统一 Worker 插件初始化与清理生命周期
|
||||
# 关闭自定义客户端等(后台任务与数据库由基类统一处理)
|
||||
...
|
||||
|
||||
# PostgreSQL 接入(可选):在插件 config.toml 配置 database 段后,
|
||||
# 基类 init_database() 检测到 url 即走 Database.from_config 接入 PG::
|
||||
#
|
||||
# # config/workers/<name>/config.toml
|
||||
# [workers.config.database]
|
||||
# type = "postgresql"
|
||||
# url = "postgresql+asyncpg://user:pwd@127.0.0.1:5432/mydb"
|
||||
# generate_schemas = true
|
||||
|
||||
# 暴露给 app lifespan 的模块级入口(bound method,签名与旧写法一致)
|
||||
plugin = MyPlugin()
|
||||
create_workers = plugin.create_workers
|
||||
@@ -39,7 +48,8 @@ Plugin 基类 — 统一 Worker 插件初始化与清理生命周期
|
||||
框架自动处理:
|
||||
- 幂等:重复 ``create_workers`` 只会初始化一次
|
||||
- 统一日志:``logger`` 自动带 ``[type]`` 前缀
|
||||
- 数据库:``_bootstrap()`` / ``init_database()`` 统一建路径、建表、记录,``cleanup`` 自动 dispose
|
||||
- 数据库:``_bootstrap()`` / ``init_database()`` 统一建库建表、记录,``cleanup`` 自动 dispose
|
||||
(SQLite 按 ``db_name`` 建库;config 含 ``database.url`` 时优先走 PostgreSQL)
|
||||
- global_var:``set_var()`` 写入插件自己的 ``global_var`` 模块(白名单由插件决定)
|
||||
- 后台任务:``spawn_task()`` 跟踪,``cleanup`` 时自动取消
|
||||
- 清理钩子:``register_cleanup()`` 注册,``cleanup`` 时逆序执行
|
||||
@@ -70,7 +80,7 @@ class Plugin:
|
||||
|
||||
#: 插件类型(worker type),必须被子类覆盖
|
||||
type: str = "default"
|
||||
#: 默认数据库文件名(data_dir 下);None 表示不自动建库
|
||||
#: 默认 SQLite 文件名(data_dir 下);config 含 database.url 时优先走 PostgreSQL;None 表示不自动建库
|
||||
db_name: str | None = None
|
||||
#: 首次初始化时自动调用 auto_bind_models
|
||||
auto_bind: bool = True
|
||||
@@ -94,11 +104,11 @@ class Plugin:
|
||||
# ------------------------------------------------------------------
|
||||
async def _bootstrap(self) -> None:
|
||||
"""
|
||||
默认资源引导:按 db_name 初始化数据库。
|
||||
默认资源引导:按 db_name(SQLite)或 database.url(PostgreSQL)初始化数据库。
|
||||
|
||||
由基类在 on_init 之前自动调用;子类需要完全自定义建库逻辑时覆写此方法。
|
||||
"""
|
||||
if self.db_name:
|
||||
if self.db_name or self._database_config().get("url"):
|
||||
await self.init_database(self.db_name)
|
||||
|
||||
async def on_init(self) -> None:
|
||||
@@ -195,15 +205,38 @@ class Plugin:
|
||||
# ------------------------------------------------------------------
|
||||
# 辅助方法
|
||||
# ------------------------------------------------------------------
|
||||
def _database_config(self) -> dict:
|
||||
"""提取运行时配置中的 database 段(不存在或非 dict 时返回空 dict)。"""
|
||||
db_conf = self.config.get("database") if isinstance(self.config, dict) else None
|
||||
if isinstance(db_conf, dict):
|
||||
return db_conf
|
||||
return {}
|
||||
|
||||
async def init_database(self, filename: str | None = None) -> Any:
|
||||
"""
|
||||
在 data_dir 下初始化 SQLite 数据库,返回 Database 实例并存入 self.db。
|
||||
初始化数据库并存入 self.db,支持两种后端:
|
||||
|
||||
- PostgreSQL:config 含 ``database.url``(如插件 config.toml 的
|
||||
``[workers.config.database]`` 配置 type/url)时优先走 ``Database.from_config``;
|
||||
- SQLite:否则在 data_dir 下按文件名建库(现有插件零改动)。
|
||||
|
||||
Args:
|
||||
filename: 数据库文件名(默认取 self.db_name)
|
||||
filename: SQLite 数据库文件名(默认取 self.db_name)
|
||||
"""
|
||||
from chongming_database import Database
|
||||
|
||||
db_conf = self._database_config()
|
||||
if db_conf.get("url"):
|
||||
db = Database.from_config(db_conf)
|
||||
await db.initialize(
|
||||
generate_schemas=db_conf.get("generate_schemas", True)
|
||||
)
|
||||
self.db = db
|
||||
self.logger.info(
|
||||
"[%s] 数据库已初始化 (PostgreSQL): %s", self.type, db_conf["url"]
|
||||
)
|
||||
return db
|
||||
|
||||
filename = filename or self.db_name
|
||||
if not filename:
|
||||
raise ValueError("未指定数据库文件名(请设置 db_name 或传入 filename)")
|
||||
|
||||
Reference in New Issue
Block a user