Code Monkey home page Code Monkey logo

nonebot-plugin-datastore's Introduction

nonebot

NoneBot Plugin DataStore

✨ NoneBot 数据存储插件 ✨

license pypi python python QQ Chat Group

安装

  • 使用 nb-cli
nb plugin install nonebot-plugin-datastore
  • 使用 pip
pip install nonebot-plugin-datastore

使用方式

先在插件代码最前面声明依赖

from nonebot import require
require("nonebot_plugin_datastore")

插件数据相关功能

from nonebot_plugin_datastore import get_plugin_data

plugin_data = get_plugin_data()

# 获取插件缓存目录
plugin_data.cache_dir
# 获取插件配置目录
plugin_data.config_dir
# 获取插件数据目录
plugin_data.data_dir

# 读取配置
await plugin_data.config.get(key)
# 存储配置
await plugin_data.config.set(key, value)

数据库相关功能,详细用法见 SQLAlchemy

from nonebot import on_command
from nonebot.params import Depends
from sqlalchemy.ext.asyncio.session import AsyncSession
from sqlalchemy.orm import Mapped, mapped_column

from nonebot_plugin_datastore import get_plugin_data, get_session

# 定义模型
Model = get_plugin_data().Model

class Example(Model):
    """示例模型"""

    id: Mapped[int] = mapped_column(primary_key=True)
    message: Mapped[str]

matcher = on_command("test")

# 数据库相关操作
@matcher.handle()
async def handle(session: AsyncSession = Depends(get_session)):
    example = Example(message="matcher")
    session.add(example)
    await session.commit()

# 因为 driver.on_startup 无法保证函数运行顺序
# 如需在 NoneBot 启动时且数据库初始化后运行的函数
# 请使用 post_db_init 而不是 Nonebot 的 on_startup
from nonebot_plugin_datastore.db import post_db_init


@post_db_init
async def do_something():
  pass

命令行支持(需安装 nb-cli 1.0+

如果使用 pipx 安装的 nb-cli,则需要运行 pip install nonebot-plugin-datastore[cli] 安装命令行所需依赖。

数据存储路径

# 获取当前数据存储路径
nb datastore dir
# 获取指定插件的数据存储路径
nb datastore dir --name plugin_name

数据库管理,详细用法见 Alembic

生成迁移文件

# 生成项目内所有启用数据库插件的迁移文件(不包括 site-packages 中的插件)
nb datastore migrate
# 生成指定插件的迁移文件
nb datastore migrate --name plugin_name -m example

升级插件数据库

# 升级所有启用数据库插件的数据库
nb datastore upgrade
# 升级指定插件的数据库
nb datastore upgrade --name plugin_name
# 升级至指定版本
nb datastore upgrade --name plugin_name revision

降级插件数据库

# 降级所有启用数据库插件的数据库
nb datastore downgrade
# 降级指定插件的数据库
nb datastore downgrade --name plugin_name
# 降级至指定版本
nb datastore downgrade --name plugin_name revision

注意

数据库迁移

推荐启动机器人前运行 nb datastore upgrade 升级数据库至最新版本。因为当前插件自动迁移依赖 NoneBoton_startup 钩子,很容易受到其他插件影响。

这里推荐 tiangolo/uvicorn-gunicorn 镜像,通过配置 prestart.sh 可确保启动机器人前运行迁移脚本。具体的例子可参考 CoolQBot

MySQL 数据库连接丢失

当使用 MySQL 时,你可能会遇到 2013: lost connection to mysql server during query 的报错。

如果遇到这种错误,可以尝试设置 pool_recycle 为一个小于数据库超时的值。或者设置 pool_pre_pingTrue

DATASTORE_ENGINE_OPTIONS={"pool_recycle": 3600}
DATASTORE_ENGINE_OPTIONS={"pool_pre_ping": true}

详细介绍可查看 SQLAlchemy 文档的 dealing-with-disconnects 章节。

SQLite 数据库已锁定

使用 SQLite 数据库时,如果在写入时遇到 (sqlite3.OperationalError) database is locked 错误。可尝试将 poolclass 设置为 StaticPool,保持有且仅有一个连接。不过这样设置之后,在程序运行期间,你的数据库文件都将被占用。

不同插件间表的关联关系

datastore 默认会给每个插件的 Base 模型提供独立的 registry,所以不同插件间的表无法建立关联关系。如果你需要与其他插件的表建立关联关系,请在需要关联的两个插件中都调用 use_global_registry 函数使用全局 registry。

# 定义模型
db = get_plugin_data()
db.use_global_registry()

class Example(db.Model):
    """实例函数"""

    id: Mapped[int] = mapped_column(primary_key=True)
    message: Mapped[str]

    tests: Mapped["Test"] = relationship(back_populates="example")


class Test(db.Model):
    id: Mapped[int] = mapped_column(primary_key=True)

    example_id: Mapped[int] = mapped_column(ForeignKey("plugin_example.id"))
    example: Mapped[Example] = relationship(back_populates="tests")

# 注意,为了避免不同插件的模型同名而报错,请一定要加上这一行,避免如下报错
# sqlalchemy.exc.InvalidRequestError: Multiple classes found for path "Test" in the registry of this declarative base. Please use a fully module-qualified path.
Example.tests = relationship(Test, back_populates="example")

配置项

配置方式:直接在 NoneBot 全局配置文件中添加以下配置项即可。

datastore_cache_dir

  • 类型: Path
  • 默认:
    • macOS: ~/Library/Caches/nonebot2
    • Unix: ~/.cache/nonebot2 (XDG default)
    • Windows: C:\Users<username>\AppData\Local\nonebot2\Cache
  • 说明: 缓存目录

datastore_config_dir

  • 类型: Path
  • 默认:
    • macOS: same as user_data_dir
    • Unix: ~/.config/nonebot2
    • Win XP (roaming): C:\Documents and Settings<username>\Local Settings\Application Data\nonebot2
    • Win 7 (roaming): C:\Users<username>\AppData\Roaming\nonebot2
  • 说明: 配置目录

datastore_data_dir

  • 类型: Path
  • 默认:
    • macOS: ~/Library/Application Support/nonebot2
    • Unix: ~/.local/share/nonebot2 or in $XDG_DATA_HOME, if defined
    • Win XP (not roaming): C:\Documents and Settings<username>\Application Data\nonebot2
    • Win 7 (not roaming): C:\Users<username>\AppData\Local\nonebot2
  • 说明: 数据目录

datastore_enable_database

  • 类型: bool
  • 默认: True
  • 说明: 是否启动数据库

datastore_database_url

  • 类型: str
  • 默认: sqlite+aiosqlite:///data_dir/data.db
  • 说明: 数据库连接字符串,默认使用 SQLite 数据库

datastore_database_echo

  • 类型: bool
  • 默认: False
  • 说明: echoecho_pool 的默认值,是否显示数据库执行的语句与其参数列表,还有连接池的相关信息

datastore_engine_options

  • 类型: dict[str, Any]
  • 默认: {}
  • 说明: 向 sqlalchemy.ext.asyncio.create_async_engine() 传递的参数

datastore_config_provider

  • 类型: str
  • 默认: ~json
  • 说明: 选择存放配置的类型,当前支持 json, yaml, toml, database 四种类型,也可设置为实现 ConfigProvider 的自定义类型。

鸣谢

nonebot-plugin-datastore's People

Contributors

dependabot[bot] avatar he0119 avatar pre-commit-ci[bot] avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

nonebot-plugin-datastore's Issues

nb新版本方法更新导致插件导入失败

NB 2.0.0-rc1版本移除了过时的Export功能,导致插件在bot启动时导入失败并引发后续插件依赖报错。
希望修复。

10-05 09:00:00 [ERROR] nonebot | Failed to import "nonebot_plugin_datastore"
Traceback (most recent call last):
(略)
ImportError: cannot import name 'export' from 'nonebot.plugin' (/usr/local/lib/python3.10/dist-packages/nonebot/plugin/init.py)

Remove: 删除过时的 Export 功能 @yanyongyu (#1125)

无法读取环境变量配置的问题

class Config(BaseModel, extra=Extra.ignore):

这个地方应该继承BaseSettings
因为nonebot的global_config对环境变量和envfile的处理有差异,写在envfile里的文件会全部load进global_config,插件config从global_config中初始化会带上global_config load的envfile里的值
但是,global_config不会load自己不认识的环境变量,所以如果这里使用BaseModel的话,是没有办法将环境变量的值引入插件config的,需要使用BaseSetting来自己读取环境变量中的值

[提议] 使用toml作为config存储格式

理由:

  1. 人类友好,方便阅读,改善开发者体验
  2. toml 已经在 Python 中大量使用,比如PEP 621 的 pyproject.toml,以及 PEP 680 在Python3.11 中添加了新内置库 tomllib

值得注意的地方:
toml 不支持 ”“ 值 ( None )

以及一个可选项将所有插件的配置项保存至一个文件(?

Bug: 加载时提示无法找到 _greenlet

描述问题

在NoneBot2启动的插件加载阶段,datastore插件在加载时有概率会引发一个由sqlalchemy抛出的ValueError,导致所有依赖datastore相关的插件都无法使用

如何复现

在NoneBot2启动阶段概率出现该问题,以下为琢磨出来的怪特征:
1.在所有插件中如果第一次require成功加载了,那后面的插件的require都会成功
2.在所有插件中如果第一次require失败了,那后面插件的require都会失败
3.尝试关闭fastapi_reload启动NoneBot2,依然会出现该问题
4.通过fastapi_reload或手动使用nb run重新加载NoneBot2,都有概率成功或失败
5.貌似最近失败概率变高了好多,以前都是低概率出现的所以懒得管它,但是最近好像加载两三次才有一次成功

环境信息

  • OS: Windows7 SP1
  • Python 版本: 3.8.10
  • Nonebot 版本: 2.0.0rc2
  • 插件版本: v0.5.10(通过git clone安装)(具体的版本不记得了www,但是刚刚更新到了0.5.10依然有这个问题)
  • sqlalchemy版本: 1.4.41

截图或日志

image
image

数据库连接断开

使用远程数据库连接时,几十分钟不访问就会出现数据库连接断开错误,可以在引擎初始化的时候使用连接池进行加载吗:
(pymysql.err.operationalerror) (2013, 'lost connection to mysql server during query ([winerror 121] 信号灯超时时间已到

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.