宝塔面板api支持批量创建数据库和用户,但需分步调用adddatabase、adddbuser和setdbpriv三个接口,严格遵循先后顺序、命名规范及字段要求,不可合并或并发执行。

宝塔面板 API 是否支持批量创建数据库和用户?
支持,但必须开启 API 并使用 /database?action=AddDatabase 和 /database?action=AddDbUser 两个接口分步执行。宝塔官方 API 文档未提供“一键绑定库+用户+权限”的合并接口,所以不能靠单次请求完成整套操作——这是自动化脚本最容易卡住的第一步。
常见错误现象:{"status":false,"msg":"数据库用户添加失败"},往往是因为先建用户后建库,或库名/用户名含非法字符(如短横线、下划线开头、纯数字),或未指定 ps(备注)字段导致接口校验失败。
- 必须先调用
AddDatabase创建库,再调用AddDbUser创建用户,最后用SetDbPriv显式授权(不能依赖“自动关联”) - 所有数据库名、用户名必须符合 MySQL 命名规范:仅含字母、数字、下划线,且不以数字开头
- API 请求头必须带
Content-Type: application/json和有效的login_token
如何构造合法的 JSON 请求体并避免 401 或 500 错误?
关键不是字段多,而是字段顺序和必填项容易遗漏。AddDatabase 必须包含 name、ps、type(固定为 mysql),而 AddDbUser 必须带 username、password、ps、type,且 username 不能与已有用户重名(哪怕属于不同库)。
示例(创建库):
{
"name": "app_v23",
"ps": "业务系统v23主库",
"type": "mysql"
}
示例(授权):SetDbPriv 接口需传 id(数据库 ID)、user_id(用户 ID)、privs(如 "SELECT,INSERT,UPDATE,DELETE"),ID 都是数字,得从上一步响应里提取,不能硬编码。
- 不要手动拼接 URL 参数,全部走 POST + JSON body
-
ps字段不能为空字符串,建议设为有意义的描述,否则部分版本宝塔会拒绝 - 密码必须满足宝塔默认强度策略(至少 8 位,含大小写字母+数字),否则返回 500
Python 脚本怎么安全地串行调用多个 API 并处理依赖关系?
不能用并发(如 asyncio.gather),因为 AddDbUser 依赖 AddDatabase 返回的 id,而 SetDbPriv 又依赖前两步的两个 ID。必须严格串行 + 检查 status == True,否则后续步骤必然失败。
使用 JSON Schema 验证 JSON 数据,从示例 JSON 生成 schema,并将其转换为 TypeScript 接口、Python 数据类或 Markdown 文档。
核心逻辑片段(简化):
import requests
url = "https://your-server:8888/database"
headers = {"Content-Type": "application/json", "login_token": "xxx"}
<h1>步骤1:建库</h1><p>r1 = requests.post(f"{url}?action=AddDatabase", json={"name":"app_01","ps":"test01","type":"mysql"}, headers=headers, verify=False)
if not r1.json().get("status"):
raise Exception(f"建库失败: {r1.text}")</p><p>db_id = r1.json()["id"]</p><h1>步骤2:建用户(注意:username 全局唯一!)</h1><p>r2 = requests.post(f"{url}?action=AddDbUser", json={"username":"u_app_01","password":"Passw0rd!2024","ps":"app01用户","type":"mysql"}, headers=headers, verify=False)
user_id = r2.json()["id"]</p><h1>步骤3:授权</h1><p>requests.post(f"{url}?action=SetDbPriv", json={"id":db_id,"user_id":user_id,"privs":"SELECT,INSERT"}, headers=headers, verify=False)</p>
- 每次请求后必须检查
r.json().get("status"),不能只看 HTTP 状态码(宝塔常返回 200 即使业务失败) -
verify=False仅用于测试,生产环境应配置证书或用requests.adapters.HTTPAdapter指定可信 CA - 用户名建议加前缀(如
u_)避免与库名冲突,也方便后期清理
批量执行时为什么部分数据库没授权成功?
大概率是 SetDbPriv 的 privs 字符串格式不对:不能有空格、不能全小写、不能漏掉逗号、不能多加引号。合法值只有类似 "SELECT,INSERT,UPDATE,DELETE" 这种大写+英文逗号分隔的形式,MySQL 权限名大小写敏感,且宝塔不会帮你自动补全或转换。
另一个隐蔽问题是:同一用户对多个库授权时,SetDbPriv 不会覆盖旧权限,而是叠加。如果之前给该用户授过 ALL PRIVILEGES,再用 SELECT,INSERT 调用一次,并不会取消 UPDATE 权限——得先 RevokeDbPriv 再重授,但该接口文档极少被提及,容易忽略。
- 调试时把每步的
r.text打印出来,比看日志更快定位哪一步崩了 - 批量量大时(比如 200+),建议加
time.sleep(0.3)避免触发宝塔的频率限制(默认 10 次/秒) - 权限字段别从 Excel 直接复制粘贴,用 Python 字符串拼接确保格式干净
最麻烦的其实是清理——API 没有批量删除数据库的接口,删库必须一个个调 DelDatabase,而且要先删用户再删库,顺序反了会报错。这点在设计自动化流程时就得预留退路。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!










