{"id":20390256,"url":"https://github.com/nonebot/plugin-orm","last_synced_at":"2025-05-07T20:39:37.604Z","repository":{"id":198007274,"uuid":"624721795","full_name":"nonebot/plugin-orm","owner":"nonebot","description":"SQLAlchemy support for NoneBot2","archived":false,"fork":false,"pushed_at":"2025-03-15T02:34:01.000Z","size":311,"stargazers_count":35,"open_issues_count":3,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-05-07T20:39:26.622Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://nonebot.dev/docs/best-practice/database/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nonebot.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"open_collective":"nonebot","custom":["https://afdian.com/@nonebot"]}},"created_at":"2023-04-07T05:23:31.000Z","updated_at":"2025-05-06T18:21:34.000Z","dependencies_parsed_at":"2023-10-11T19:24:36.389Z","dependency_job_id":"287ddd6e-a2eb-46a7-b203-7e3c9602489b","html_url":"https://github.com/nonebot/plugin-orm","commit_stats":{"total_commits":99,"total_committers":4,"mean_commits":24.75,"dds":0.08080808080808077,"last_synced_commit":"ea60f12c4a86e2f227cc2a662d624fcda307a3f8"},"previous_names":["nonebot/plugin-orm"],"tags_count":25,"template":false,"template_full_name":"yanyongyu/python-poetry-template","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nonebot%2Fplugin-orm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nonebot%2Fplugin-orm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nonebot%2Fplugin-orm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nonebot%2Fplugin-orm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nonebot","download_url":"https://codeload.github.com/nonebot/plugin-orm/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252954126,"owners_count":21830892,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-15T03:23:54.405Z","updated_at":"2025-05-07T20:39:37.584Z","avatar_url":"https://github.com/nonebot.png","language":"Python","funding_links":["https://opencollective.com/nonebot","https://afdian.com/@nonebot"],"categories":[],"sub_categories":[],"readme":"\u003c!-- markdownlint-disable MD033 MD041 --\u003e\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://nonebot.dev/\"\u003e\u003cimg src=\"https://nonebot.dev/logo.png\" width=\"200\" height=\"200\" alt=\"nonebot\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cdiv align=\"center\"\u003e\n\n# NoneBot Plugin ORM\n\n\u003c!-- prettier-ignore-start --\u003e\n\u003c!-- markdownlint-disable-next-line MD036 --\u003e\n_✨ NoneBot 数据库支持插件 ✨_\n\u003c!-- prettier-ignore-end --\u003e\n\n\u003c/div\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://raw.githubusercontent.com/nonebot/plugin-orm/master/LICENSE\"\u003e\n    \u003cimg src=\"https://img.shields.io/github/license/nonebot/plugin-orm.svg\" alt=\"license\"\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://pypi.org/project/nonebot-plugin-orm/\"\u003e\n    \u003cimg src=\"https://img.shields.io/pypi/v/nonebot-plugin-orm.svg\" alt=\"pypi\"\u003e\n  \u003c/a\u003e\n  \u003cimg src=\"https://img.shields.io/badge/python-3.8+-blue.svg\" alt=\"python\"\u003e\n\u003c/p\u003e\n\n## 安装\n\n```shell\npip install nonebot-plugin-orm\npoetry add nonebot-plugin-orm\npdm add nonebot-plugin-orm\n\n# 无需配置、开箱即用的默认依赖\npip install nonebot-plugin-orm[default]\n\n# 特定数据库后端的依赖\npip install nonebot-plugin-orm[mysql]\npip install nonebot-plugin-orm[postgresql]\npip install nonebot-plugin-orm[sqlite]\n\n# 特定数据库驱动的依赖\npip install nonebot-plugin-orm[asyncmy]\npip install nonebot-plugin-orm[aiomysql]\npip install nonebot-plugin-orm[psycopg]\npip install nonebot-plugin-orm[asyncpg]\npip install nonebot-plugin-orm[aiosqlite]\n```\n\n## 使用方式\n\n### ORM\n\n#### Model 依赖注入\n\n```python\nfrom nonebot.adapters import Event\nfrom nonebot.params import Depends\nfrom nonebot import require, on_message\nfrom sqlalchemy.orm import Mapped, mapped_column\n\nrequire(\"nonebot_plugin_orm\")\nfrom nonebot_plugin_orm import Model, async_scoped_session\n\nmatcher = on_message()\n\n\ndef get_user_id(event: Event) -\u003e str:\n    return event.get_user_id()\n\n\nclass User(Model):\n    id: Mapped[int] = mapped_column(primary_key=True)\n    user_id: Mapped[str] = Depends(get_user_id)\n\n\n@matcher.handle()\nasync def _(event: Event, sess: async_scoped_session, user: User | None):\n    if user:\n        await matcher.finish(f\"Hello, {user.user_id}\")\n\n    sess.add(User(user_id=get_user_id(event)))\n    await sess.commit()\n    await matcher.finish(\"Hello, new user!\")\n```\n\n#### SQL 依赖注入\n\n```python\nfrom sqlalchemy import select\nfrom nonebot.adapters import Event\nfrom nonebot.params import Depends\nfrom nonebot import require, on_message\nfrom sqlalchemy.orm import Mapped, mapped_column\n\nrequire(\"nonebot_plugin_orm\")\nfrom nonebot_plugin_orm import Model, SQLDepends, async_scoped_session\n\nmatcher = on_message()\n\n\ndef get_session_id(event: Event) -\u003e str:\n    return event.get_session_id()\n\n\nclass Session(Model):\n    id: Mapped[int] = mapped_column(primary_key=True)\n    session_id: Mapped[str]\n\n\n@matcher.handle()\nasync def _(\n    event: Event,\n    sess: async_scoped_session,\n    session: Session\n    | None = SQLDepends(\n        select(Session).where(Session.session_id == Depends(get_session_id))\n    ),\n):\n    if session:\n        await matcher.finish(f\"Hello, {session.session_id}\")\n\n    sess.add(Session(session_id=get_session_id(event)))\n    await sess.commit()\n    await matcher.finish(\"Hello, new user!\")\n\n```\n\n### CLI\n\n依赖 [NB CLI](https://github.com/nonebot/nb-cli)\n\n```properties\n$ nb orm\nUsage: nb orm [OPTIONS] COMMAND [ARGS]...\n\nOptions:\n  -c, --config FILE  可选的配置文件；默认为 ALEMBIC_CONFIG 环境变量的值，或者 \"alembic.ini\"（如果存在）\n  -n, --name TEXT    .ini 文件中用于 Alembic 配置的小节的名称  [default: alembic]\n  -x TEXT            自定义 env.py 脚本使用的其他参数，例如：-x setting1=somesetting -x\n                     setting2=somesetting\n  -q, --quite        不要输出日志到标准输出\n  --help             Show this message and exit.\n\nCommands:\n  branches        显示所有的分支。\n  check           检查数据库是否与模型定义一致。\n  current         显示当前的迁移。\n  downgrade       回退到先前版本。\n  edit            使用 $EDITOR 编辑迁移脚本。\n  ensure_version  创建版本表。\n  heads           显示所有的分支头。\n  history         显示迁移的历史。\n  init            初始化脚本目录。\n  list_templates  列出所有可用的模板。\n  merge           合并多个迁移。创建一个新的迁移脚本。\n  revision        创建一个新迁移脚本。\n  show            显示迁移的信息。\n  stamp           将数据库标记为特定的迁移版本，不运行任何迁移。\n  upgrade         升级到较新版本。\n```\n\n## 配置项\n\n### sqlalchemy_database_url\n\n默认数据库连接 URL。\n参见：[Engine Configuration — SQLAlchemy 2.0 Documentation](https://docs.sqlalchemy.org/en/20/core/engines.html#database-urls)\n\n```properties\nSQLALCHEMY_DATABASE_URL=sqlite+aiosqlite://\n```\n\n### sqlalchemy_binds\n\nbind keys 到 `AsyncEngine` 选项的映射。值可以是数据库连接 URL、`AsyncEngine` 选项字典或者 `AsyncEngine` 实例。\n\n```properties\nSQLALCHEMY_BINDS='{\n    \"\": \"sqlite+aiosqlite://\",\n    \"nonebot_plugin_user\": {\n        \"url\": \"postgresql+asyncpg://scott:tiger@localhost/mydatabase\",\n        \"echo\": true\n    }\n}'\n```\n\n### sqlalchemy_echo\n\n所有 `AsyncEngine` 的 `echo` 和 `echo_pool` 选项的默认值。用于快速调试连接和 SQL 生成问题。\n\n```properties\nSQLALCHEMY_ECHO=true\n```\n\n### sqlalchemy_engine_options\n\n所有 `AsyncEngine` 的默认选项字典。\n参见：[Engine Configuration — SQLAlchemy 2.0 Documentation](https://docs.sqlalchemy.org/en/20/core/engines.html#engine-configuration)\n\n```properties\nSQLALCHEMY_ENGINE_OPTIONS='{\n    \"pool_size\": 5,\n    \"max_overflow\": 10,\n    \"pool_timeout\": 30,\n    \"pool_recycle\": 3600,\n    \"echo\": true\n}'\n```\n\n### sqlalchemy_session_options\n\n`AsyncSession` 的选项字典。\n参见：[Session API — SQLAlchemy 2.0 Documentation](https://docs.sqlalchemy.org/en/20/orm/session_api.html#sqlalchemy.orm.Session.__init__)\n\n```properties\nSQLALCHEMY_SESSION_OPTIONS='{\n    \"autoflush\": false,\n    \"autobegin\": true,\n    \"expire_on_commit\": true\n}'\n```\n\n### alembic_config\n\n配置文件路径或 `AlembicConfig` 实例。\n\n```properties\nALEMBIC_CONFIG=alembic.ini\n```\n\n### alembic_script_location\n\n脚本目录路径。\n\n```properties\nALEMBIC_SCRIPT_LOCATION=migrations\n```\n\n### alembic_version_locations\n\n迁移脚本目录路径或分支标签到迁移脚本目录路径的映射。\n\n```properties\nALEMBIC_VERSION_LOCATIONS=migrations/versions\n\nALEMBIC_VERSION_LOCATIONS='{\n    \"\": \"migrations/versions\",\n    \"nonebot_plugin_user\": \"src/nonebot_plugin_user/versions\",\n    \"nonebot_plugin_chatrecorder\": \"migrations/versions/nonebot_plugin_chatrecorder\"\n}'\n```\n\n### alembic_context\n\n`MigrationContext` 的选项字典。\n参见：[Runtime Objects — Alembic 1.12.0 documentation](https://alembic.sqlalchemy.org/en/latest/api/runtime.html#alembic.runtime.environment.EnvironmentContext.configure)\n\n```properties\nALEMBIC_CONTEXT='{\n    \"render_as_batch\": true\n}'\n```\n\n### alembic_startup_check\n\n是否在启动时检查数据库与模型定义的一致性。\n\n```properties\nALEMBIC_STARTUP_CHECK=true\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnonebot%2Fplugin-orm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnonebot%2Fplugin-orm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnonebot%2Fplugin-orm/lists"}