nonebot-plugin-datastore


Namenonebot-plugin-datastore JSON
Version 1.1.2 PyPI version JSON
download
home_pagehttps://github.com/he0119/nonebot-plugin-datastore
Summary适用于 Nonebot2 的数据存储插件
upload_time2023-09-15 02:35:31
maintainer
docs_urlNone
authorhemengyang
requires_python>=3.8,<4.0
licenseMIT
keywords
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            <!-- markdownlint-disable MD033 MD036 MD041 -->

<p align="center">
  <a href="https://v2.nonebot.dev/"><img src="https://v2.nonebot.dev/logo.png" width="200" height="200" alt="nonebot"></a>
</p>

<div align="center">

# NoneBot Plugin DataStore

_✨ NoneBot 数据存储插件 ✨_

</div>

<p align="center">
  <a href="https://raw.githubusercontent.com/he0119/nonebot-plugin-datastore/main/LICENSE">
    <img src="https://img.shields.io/github/license/he0119/nonebot-plugin-datastore.svg" alt="license">
  </a>
  <a href="https://pypi.python.org/pypi/nonebot-plugin-datastore">
    <img src="https://img.shields.io/pypi/v/nonebot-plugin-datastore.svg" alt="pypi">
  </a>
  <img src="https://img.shields.io/badge/python-3.8+-blue.svg" alt="python">
  <a href="https://codecov.io/gh/he0119/nonebot-plugin-datastore">
    <img src="https://codecov.io/gh/he0119/nonebot-plugin-datastore/branch/main/graph/badge.svg?token=jd5ufc1alv"/>
  </a>
  <a href="https://jq.qq.com/?_wv=1027&k=7zQUpiGp">
    <img src="https://img.shields.io/badge/QQ%E7%BE%A4-730374631-orange?style=flat-square" alt="QQ Chat Group">
  </a>
</p>

## 安装

- 使用 nb-cli

```sh
nb plugin install nonebot-plugin-datastore
```

- 使用 pip

```sh
pip install nonebot-plugin-datastore
```

## 使用方式

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

```python
from nonebot import require
require("nonebot_plugin_datastore")
```

### 插件数据相关功能

```python
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](https://docs.sqlalchemy.org/orm/quickstart.html)

```python
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+](https://github.com/nonebot/nb-cli))

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

#### 数据存储路径

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

#### 数据库管理,详细用法见 [Alembic](https://alembic.sqlalchemy.org/en/latest/)

生成迁移文件

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

升级插件数据库

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

降级插件数据库

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

## 注意

### 数据库迁移

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

这里推荐 [tiangolo/uvicorn-gunicorn](https://github.com/tiangolo/uvicorn-gunicorn-docker) 镜像,通过配置 `prestart.sh` 可确保启动机器人前运行迁移脚本。具体的例子可参考 [CoolQBot](https://github.com/he0119/CoolQBot/)。

### MySQL 数据库连接丢失

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

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

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

详细介绍可查看 `SQLAlchemy` 文档的 [dealing-with-disconnects](https://docs.sqlalchemy.org/en/20/core/pooling.html#dealing-with-disconnects) 章节。

### SQLite 数据库已锁定

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

### 不同插件间表的关联关系

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

```python
# 定义模型
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`
- 说明: `echo` 和 `echo_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 LocalStore`](https://github.com/nonebot/plugin-localstore): 提供了默认的文件存储位置
- [`Flask-SQLAlchemy`](https://github.com/pallets-eco/flask-sqlalchemy/): 借鉴了数据库的实现思路
- [`Flask-Alembic`](https://github.com/davidism/flask-alembic): 借鉴了命令行的实现思路


            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/he0119/nonebot-plugin-datastore",
    "name": "nonebot-plugin-datastore",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.8,<4.0",
    "maintainer_email": "",
    "keywords": "",
    "author": "hemengyang",
    "author_email": "hmy0119@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/36/0d/b95402b0e50f9e948dcbbd13f3cbac515ae30dad7258a9ce3e6e20dfae13/nonebot_plugin_datastore-1.1.2.tar.gz",
    "platform": null,
    "description": "<!-- markdownlint-disable MD033 MD036 MD041 -->\n\n<p align=\"center\">\n  <a href=\"https://v2.nonebot.dev/\"><img src=\"https://v2.nonebot.dev/logo.png\" width=\"200\" height=\"200\" alt=\"nonebot\"></a>\n</p>\n\n<div align=\"center\">\n\n# NoneBot Plugin DataStore\n\n_\u2728 NoneBot \u6570\u636e\u5b58\u50a8\u63d2\u4ef6 \u2728_\n\n</div>\n\n<p align=\"center\">\n  <a href=\"https://raw.githubusercontent.com/he0119/nonebot-plugin-datastore/main/LICENSE\">\n    <img src=\"https://img.shields.io/github/license/he0119/nonebot-plugin-datastore.svg\" alt=\"license\">\n  </a>\n  <a href=\"https://pypi.python.org/pypi/nonebot-plugin-datastore\">\n    <img src=\"https://img.shields.io/pypi/v/nonebot-plugin-datastore.svg\" alt=\"pypi\">\n  </a>\n  <img src=\"https://img.shields.io/badge/python-3.8+-blue.svg\" alt=\"python\">\n  <a href=\"https://codecov.io/gh/he0119/nonebot-plugin-datastore\">\n    <img src=\"https://codecov.io/gh/he0119/nonebot-plugin-datastore/branch/main/graph/badge.svg?token=jd5ufc1alv\"/>\n  </a>\n  <a href=\"https://jq.qq.com/?_wv=1027&k=7zQUpiGp\">\n    <img src=\"https://img.shields.io/badge/QQ%E7%BE%A4-730374631-orange?style=flat-square\" alt=\"QQ Chat Group\">\n  </a>\n</p>\n\n## \u5b89\u88c5\n\n- \u4f7f\u7528 nb-cli\n\n```sh\nnb plugin install nonebot-plugin-datastore\n```\n\n- \u4f7f\u7528 pip\n\n```sh\npip install nonebot-plugin-datastore\n```\n\n## \u4f7f\u7528\u65b9\u5f0f\n\n\u5148\u5728\u63d2\u4ef6\u4ee3\u7801\u6700\u524d\u9762\u58f0\u660e\u4f9d\u8d56\n\n```python\nfrom nonebot import require\nrequire(\"nonebot_plugin_datastore\")\n```\n\n### \u63d2\u4ef6\u6570\u636e\u76f8\u5173\u529f\u80fd\n\n```python\nfrom nonebot_plugin_datastore import get_plugin_data\n\nplugin_data = get_plugin_data()\n\n# \u83b7\u53d6\u63d2\u4ef6\u7f13\u5b58\u76ee\u5f55\nplugin_data.cache_dir\n# \u83b7\u53d6\u63d2\u4ef6\u914d\u7f6e\u76ee\u5f55\nplugin_data.config_dir\n# \u83b7\u53d6\u63d2\u4ef6\u6570\u636e\u76ee\u5f55\nplugin_data.data_dir\n\n# \u8bfb\u53d6\u914d\u7f6e\nawait plugin_data.config.get(key)\n# \u5b58\u50a8\u914d\u7f6e\nawait plugin_data.config.set(key, value)\n```\n\n### \u6570\u636e\u5e93\u76f8\u5173\u529f\u80fd\uff0c\u8be6\u7ec6\u7528\u6cd5\u89c1 [SQLAlchemy](https://docs.sqlalchemy.org/orm/quickstart.html)\n\n```python\nfrom nonebot import on_command\nfrom nonebot.params import Depends\nfrom sqlalchemy.ext.asyncio.session import AsyncSession\nfrom sqlalchemy.orm import Mapped, mapped_column\n\nfrom nonebot_plugin_datastore import get_plugin_data, get_session\n\n# \u5b9a\u4e49\u6a21\u578b\nModel = get_plugin_data().Model\n\nclass Example(Model):\n    \"\"\"\u793a\u4f8b\u6a21\u578b\"\"\"\n\n    id: Mapped[int] = mapped_column(primary_key=True)\n    message: Mapped[str]\n\nmatcher = on_command(\"test\")\n\n# \u6570\u636e\u5e93\u76f8\u5173\u64cd\u4f5c\n@matcher.handle()\nasync def handle(session: AsyncSession = Depends(get_session)):\n    example = Example(message=\"matcher\")\n    session.add(example)\n    await session.commit()\n\n# \u56e0\u4e3a driver.on_startup \u65e0\u6cd5\u4fdd\u8bc1\u51fd\u6570\u8fd0\u884c\u987a\u5e8f\n# \u5982\u9700\u5728 NoneBot \u542f\u52a8\u65f6\u4e14\u6570\u636e\u5e93\u521d\u59cb\u5316\u540e\u8fd0\u884c\u7684\u51fd\u6570\n# \u8bf7\u4f7f\u7528 post_db_init \u800c\u4e0d\u662f Nonebot \u7684 on_startup\nfrom nonebot_plugin_datastore.db import post_db_init\n\n\n@post_db_init\nasync def do_something():\n  pass\n```\n\n### \u547d\u4ee4\u884c\u652f\u6301\uff08\u9700\u5b89\u88c5 [nb-cli 1.0+](https://github.com/nonebot/nb-cli)\uff09\n\n\u5982\u679c\u4f7f\u7528 pipx \u5b89\u88c5\u7684 nb-cli\uff0c\u5219\u9700\u8981\u8fd0\u884c `pip install nonebot-plugin-datastore[cli]` \u5b89\u88c5\u547d\u4ee4\u884c\u6240\u9700\u4f9d\u8d56\u3002\n\n#### \u6570\u636e\u5b58\u50a8\u8def\u5f84\n\n```shell\n# \u83b7\u53d6\u5f53\u524d\u6570\u636e\u5b58\u50a8\u8def\u5f84\nnb datastore dir\n# \u83b7\u53d6\u6307\u5b9a\u63d2\u4ef6\u7684\u6570\u636e\u5b58\u50a8\u8def\u5f84\nnb datastore dir --name plugin_name\n```\n\n#### \u6570\u636e\u5e93\u7ba1\u7406\uff0c\u8be6\u7ec6\u7528\u6cd5\u89c1 [Alembic](https://alembic.sqlalchemy.org/en/latest/)\n\n\u751f\u6210\u8fc1\u79fb\u6587\u4ef6\n\n```shell\n# \u751f\u6210\u9879\u76ee\u5185\u6240\u6709\u542f\u7528\u6570\u636e\u5e93\u63d2\u4ef6\u7684\u8fc1\u79fb\u6587\u4ef6\uff08\u4e0d\u5305\u62ec site-packages \u4e2d\u7684\u63d2\u4ef6\uff09\nnb datastore migrate\n# \u751f\u6210\u6307\u5b9a\u63d2\u4ef6\u7684\u8fc1\u79fb\u6587\u4ef6\nnb datastore migrate --name plugin_name -m example\n```\n\n\u5347\u7ea7\u63d2\u4ef6\u6570\u636e\u5e93\n\n```shell\n# \u5347\u7ea7\u6240\u6709\u542f\u7528\u6570\u636e\u5e93\u63d2\u4ef6\u7684\u6570\u636e\u5e93\nnb datastore upgrade\n# \u5347\u7ea7\u6307\u5b9a\u63d2\u4ef6\u7684\u6570\u636e\u5e93\nnb datastore upgrade --name plugin_name\n# \u5347\u7ea7\u81f3\u6307\u5b9a\u7248\u672c\nnb datastore upgrade --name plugin_name revision\n```\n\n\u964d\u7ea7\u63d2\u4ef6\u6570\u636e\u5e93\n\n```shell\n# \u964d\u7ea7\u6240\u6709\u542f\u7528\u6570\u636e\u5e93\u63d2\u4ef6\u7684\u6570\u636e\u5e93\nnb datastore downgrade\n# \u964d\u7ea7\u6307\u5b9a\u63d2\u4ef6\u7684\u6570\u636e\u5e93\nnb datastore downgrade --name plugin_name\n# \u964d\u7ea7\u81f3\u6307\u5b9a\u7248\u672c\nnb datastore downgrade --name plugin_name revision\n```\n\n## \u6ce8\u610f\n\n### \u6570\u636e\u5e93\u8fc1\u79fb\n\n\u63a8\u8350\u542f\u52a8\u673a\u5668\u4eba\u524d\u8fd0\u884c `nb datastore upgrade` \u5347\u7ea7\u6570\u636e\u5e93\u81f3\u6700\u65b0\u7248\u672c\u3002\u56e0\u4e3a\u5f53\u524d\u63d2\u4ef6\u81ea\u52a8\u8fc1\u79fb\u4f9d\u8d56 `NoneBot` \u7684 `on_startup` \u94a9\u5b50\uff0c\u5f88\u5bb9\u6613\u53d7\u5230\u5176\u4ed6\u63d2\u4ef6\u5f71\u54cd\u3002\n\n\u8fd9\u91cc\u63a8\u8350 [tiangolo/uvicorn-gunicorn](https://github.com/tiangolo/uvicorn-gunicorn-docker) \u955c\u50cf\uff0c\u901a\u8fc7\u914d\u7f6e `prestart.sh` \u53ef\u786e\u4fdd\u542f\u52a8\u673a\u5668\u4eba\u524d\u8fd0\u884c\u8fc1\u79fb\u811a\u672c\u3002\u5177\u4f53\u7684\u4f8b\u5b50\u53ef\u53c2\u8003 [CoolQBot](https://github.com/he0119/CoolQBot/)\u3002\n\n### MySQL \u6570\u636e\u5e93\u8fde\u63a5\u4e22\u5931\n\n\u5f53\u4f7f\u7528 `MySQL` \u65f6\uff0c\u4f60\u53ef\u80fd\u4f1a\u9047\u5230 `2013: lost connection to mysql server during query` \u7684\u62a5\u9519\u3002\n\n\u5982\u679c\u9047\u5230\u8fd9\u79cd\u9519\u8bef\uff0c\u53ef\u4ee5\u5c1d\u8bd5\u8bbe\u7f6e `pool_recycle` \u4e3a\u4e00\u4e2a\u5c0f\u4e8e\u6570\u636e\u5e93\u8d85\u65f6\u7684\u503c\u3002\u6216\u8005\u8bbe\u7f6e `pool_pre_ping` \u4e3a `True`\u3002\n\n```env\nDATASTORE_ENGINE_OPTIONS={\"pool_recycle\": 3600}\nDATASTORE_ENGINE_OPTIONS={\"pool_pre_ping\": true}\n```\n\n\u8be6\u7ec6\u4ecb\u7ecd\u53ef\u67e5\u770b `SQLAlchemy` \u6587\u6863\u7684 [dealing-with-disconnects](https://docs.sqlalchemy.org/en/20/core/pooling.html#dealing-with-disconnects) \u7ae0\u8282\u3002\n\n### SQLite \u6570\u636e\u5e93\u5df2\u9501\u5b9a\n\n\u4f7f\u7528 `SQLite` \u6570\u636e\u5e93\u65f6\uff0c\u5982\u679c\u5728\u5199\u5165\u65f6\u9047\u5230 `(sqlite3.OperationalError) database is locked` \u9519\u8bef\u3002\u53ef\u5c1d\u8bd5\u5c06 `poolclass` \u8bbe\u7f6e\u4e3a `StaticPool`\uff0c\u4fdd\u6301\u6709\u4e14\u4ec5\u6709\u4e00\u4e2a\u8fde\u63a5\u3002\u4e0d\u8fc7\u8fd9\u6837\u8bbe\u7f6e\u4e4b\u540e\uff0c\u5728\u7a0b\u5e8f\u8fd0\u884c\u671f\u95f4\uff0c\u4f60\u7684\u6570\u636e\u5e93\u6587\u4ef6\u90fd\u5c06\u88ab\u5360\u7528\u3002\n\n### \u4e0d\u540c\u63d2\u4ef6\u95f4\u8868\u7684\u5173\u8054\u5173\u7cfb\n\ndatastore \u9ed8\u8ba4\u4f1a\u7ed9\u6bcf\u4e2a\u63d2\u4ef6\u7684 Base \u6a21\u578b\u63d0\u4f9b\u72ec\u7acb\u7684 registry\uff0c\u6240\u4ee5\u4e0d\u540c\u63d2\u4ef6\u95f4\u7684\u8868\u65e0\u6cd5\u5efa\u7acb\u5173\u8054\u5173\u7cfb\u3002\u5982\u679c\u4f60\u9700\u8981\u4e0e\u5176\u4ed6\u63d2\u4ef6\u7684\u8868\u5efa\u7acb\u5173\u8054\u5173\u7cfb\uff0c\u8bf7\u5728\u9700\u8981\u5173\u8054\u7684\u4e24\u4e2a\u63d2\u4ef6\u4e2d\u90fd\u8c03\u7528 use_global_registry \u51fd\u6570\u4f7f\u7528\u5168\u5c40 registry\u3002\n\n```python\n# \u5b9a\u4e49\u6a21\u578b\ndb = get_plugin_data()\ndb.use_global_registry()\n\nclass Example(db.Model):\n    \"\"\"\u5b9e\u4f8b\u51fd\u6570\"\"\"\n\n    id: Mapped[int] = mapped_column(primary_key=True)\n    message: Mapped[str]\n\n    tests: Mapped[\"Test\"] = relationship(back_populates=\"example\")\n\n\nclass Test(db.Model):\n    id: Mapped[int] = mapped_column(primary_key=True)\n\n    example_id: Mapped[int] = mapped_column(ForeignKey(\"plugin_example.id\"))\n    example: Mapped[Example] = relationship(back_populates=\"tests\")\n\n# \u6ce8\u610f\uff0c\u4e3a\u4e86\u907f\u514d\u4e0d\u540c\u63d2\u4ef6\u7684\u6a21\u578b\u540c\u540d\u800c\u62a5\u9519\uff0c\u8bf7\u4e00\u5b9a\u8981\u52a0\u4e0a\u8fd9\u4e00\u884c\uff0c\u907f\u514d\u5982\u4e0b\u62a5\u9519\n# sqlalchemy.exc.InvalidRequestError: Multiple classes found for path \"Test\" in the registry of this declarative base. Please use a fully module-qualified path.\nExample.tests = relationship(Test, back_populates=\"example\")\n```\n\n## \u914d\u7f6e\u9879\n\n\u914d\u7f6e\u65b9\u5f0f\uff1a\u76f4\u63a5\u5728 `NoneBot` \u5168\u5c40\u914d\u7f6e\u6587\u4ef6\u4e2d\u6dfb\u52a0\u4ee5\u4e0b\u914d\u7f6e\u9879\u5373\u53ef\u3002\n\n### datastore_cache_dir\n\n- \u7c7b\u578b: `Path`\n- \u9ed8\u8ba4:\n  - macOS: ~/Library/Caches/nonebot2\n  - Unix: ~/.cache/nonebot2 (XDG default)\n  - Windows: C:\\Users\\<username>\\AppData\\Local\\nonebot2\\Cache\n- \u8bf4\u660e: \u7f13\u5b58\u76ee\u5f55\n\n### datastore_config_dir\n\n- \u7c7b\u578b: `Path`\n- \u9ed8\u8ba4:\n  - macOS: same as user_data_dir\n  - Unix: ~/.config/nonebot2\n  - Win XP (roaming): C:\\Documents and Settings\\<username>\\Local Settings\\Application Data\\nonebot2\n  - Win 7 (roaming): C:\\Users\\<username>\\AppData\\Roaming\\nonebot2\n- \u8bf4\u660e: \u914d\u7f6e\u76ee\u5f55\n\n### datastore_data_dir\n\n- \u7c7b\u578b: `Path`\n- \u9ed8\u8ba4:\n  - macOS: ~/Library/Application Support/nonebot2\n  - Unix: ~/.local/share/nonebot2 or in $XDG_DATA_HOME, if defined\n  - Win XP (not roaming): C:\\Documents and Settings\\<username>\\Application Data\\nonebot2\n  - Win 7 (not roaming): C:\\Users\\<username>\\AppData\\Local\\nonebot2\n- \u8bf4\u660e: \u6570\u636e\u76ee\u5f55\n\n### datastore_enable_database\n\n- \u7c7b\u578b: `bool`\n- \u9ed8\u8ba4: `True`\n- \u8bf4\u660e: \u662f\u5426\u542f\u52a8\u6570\u636e\u5e93\n\n### datastore_database_url\n\n- \u7c7b\u578b: `str`\n- \u9ed8\u8ba4: `sqlite+aiosqlite:///data_dir/data.db`\n- \u8bf4\u660e: \u6570\u636e\u5e93\u8fde\u63a5\u5b57\u7b26\u4e32\uff0c\u9ed8\u8ba4\u4f7f\u7528 SQLite \u6570\u636e\u5e93\n\n### datastore_database_echo\n\n- \u7c7b\u578b: `bool`\n- \u9ed8\u8ba4: `False`\n- \u8bf4\u660e: `echo` \u548c `echo_pool` \u7684\u9ed8\u8ba4\u503c\uff0c\u662f\u5426\u663e\u793a\u6570\u636e\u5e93\u6267\u884c\u7684\u8bed\u53e5\u4e0e\u5176\u53c2\u6570\u5217\u8868\uff0c\u8fd8\u6709\u8fde\u63a5\u6c60\u7684\u76f8\u5173\u4fe1\u606f\n\n### datastore_engine_options\n\n- \u7c7b\u578b: `dict[str, Any]`\n- \u9ed8\u8ba4: `{}`\n- \u8bf4\u660e: \u5411 `sqlalchemy.ext.asyncio.create_async_engine()` \u4f20\u9012\u7684\u53c2\u6570\n\n### datastore_config_provider\n\n- \u7c7b\u578b: `str`\n- \u9ed8\u8ba4: `~json`\n- \u8bf4\u660e: \u9009\u62e9\u5b58\u653e\u914d\u7f6e\u7684\u7c7b\u578b\uff0c\u5f53\u524d\u652f\u6301 json, yaml, toml, database \u56db\u79cd\u7c7b\u578b\uff0c\u4e5f\u53ef\u8bbe\u7f6e\u4e3a\u5b9e\u73b0 `ConfigProvider` \u7684\u81ea\u5b9a\u4e49\u7c7b\u578b\u3002\n\n## \u9e23\u8c22\n\n- [`NoneBot Plugin LocalStore`](https://github.com/nonebot/plugin-localstore): \u63d0\u4f9b\u4e86\u9ed8\u8ba4\u7684\u6587\u4ef6\u5b58\u50a8\u4f4d\u7f6e\n- [`Flask-SQLAlchemy`](https://github.com/pallets-eco/flask-sqlalchemy/): \u501f\u9274\u4e86\u6570\u636e\u5e93\u7684\u5b9e\u73b0\u601d\u8def\n- [`Flask-Alembic`](https://github.com/davidism/flask-alembic): \u501f\u9274\u4e86\u547d\u4ee4\u884c\u7684\u5b9e\u73b0\u601d\u8def\n\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "\u9002\u7528\u4e8e Nonebot2 \u7684\u6570\u636e\u5b58\u50a8\u63d2\u4ef6",
    "version": "1.1.2",
    "project_urls": {
        "Documentation": "https://github.com/he0119/nonebot-plugin-datastore#readme",
        "Homepage": "https://github.com/he0119/nonebot-plugin-datastore",
        "Repository": "https://github.com/he0119/nonebot-plugin-datastore"
    },
    "split_keywords": [],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "cece3ef10073cf383165b3c1dd1209b16c93236c32d41819d70ea9bb995d70a8",
                "md5": "3c63fc420e096277147e0a4c04df8f19",
                "sha256": "e61044e018c6b60701b38a078b5d0c1ff87e924ee1722675a14006cc32039b05"
            },
            "downloads": -1,
            "filename": "nonebot_plugin_datastore-1.1.2-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "3c63fc420e096277147e0a4c04df8f19",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8,<4.0",
            "size": 25916,
            "upload_time": "2023-09-15T02:35:29",
            "upload_time_iso_8601": "2023-09-15T02:35:29.872538Z",
            "url": "https://files.pythonhosted.org/packages/ce/ce/3ef10073cf383165b3c1dd1209b16c93236c32d41819d70ea9bb995d70a8/nonebot_plugin_datastore-1.1.2-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "360db95402b0e50f9e948dcbbd13f3cbac515ae30dad7258a9ce3e6e20dfae13",
                "md5": "10698d44f47e82f36463b77b1b5fa52b",
                "sha256": "32d06d0b06b32d2c02fb3f206820e0da64e0dde542cff3b8aa44abd93b3aeada"
            },
            "downloads": -1,
            "filename": "nonebot_plugin_datastore-1.1.2.tar.gz",
            "has_sig": false,
            "md5_digest": "10698d44f47e82f36463b77b1b5fa52b",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8,<4.0",
            "size": 21842,
            "upload_time": "2023-09-15T02:35:31",
            "upload_time_iso_8601": "2023-09-15T02:35:31.253971Z",
            "url": "https://files.pythonhosted.org/packages/36/0d/b95402b0e50f9e948dcbbd13f3cbac515ae30dad7258a9ce3e6e20dfae13/nonebot_plugin_datastore-1.1.2.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-09-15 02:35:31",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "he0119",
    "github_project": "nonebot-plugin-datastore",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "nonebot-plugin-datastore"
}
        
Elapsed time: 0.11163s