关于 frappe-ops-upgrades
为 Frappe/ERPNext 管理员和开发者提供 v14、v15、v16 大版本升级参考,涵盖迁移、故障处理与回滚。还说明自定义应用兼容性及站点间迁移定制内容的方法。
主要功能
- 01升级前检查与版本切换
- 02迁移补丁的管理和排错
- 03备份与安全回滚步骤
- 04自定义应用兼容性检查
- 05使用 Packages 与 Fixtures 迁移定制内容
适用场景
- 01规划 Frappe 大版本升级
- 02排查失败或卡住的迁移补丁
- 03升级失败后恢复站点
- 04在不同站点间迁移应用定制
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ impertio-studio/ frappe_claude_skill_package --skill frappe-ops-upgrades安装后在 Claude Code 中输入/frappe-ops-upgrades确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/.gitkeepanti-patterns.mdbreaking-changes.mdexamples.mdfrappe-packages.md详细介绍
版本升级
完整指南:如何在 Frappe/ERPNext 的主要版本之间升级、处理失败的迁移以及安全回滚。
版本:v14 → v15 → v16
快速参考:升级命令
| 任务 | 命令 |
|---|---|
| 完整更新 | bench update |
| 更新指定应用 | bench update --pull --app erpnext |
| 切换分支 | bench switch-to-branch version-15 frappe erpnext |
| 仅运行迁移 | bench --site mysite migrate |
| 检查迁移就绪状态 | bench --site mysite ready-for-migration |
| 升级前备份 | bench --site mysite backup |
| 从备份恢复 | bench --site mysite restore /path/to/backup.sql.gz |
| 重新运行失败的补丁 | 在 patches.txt 中添加 #YYYY-MM-DD 后缀 |
决策树:升级策略
Need to upgrade?
├── Single minor version bump (e.g., v15.10 → v15.20)?
│ └── YES → Run `bench update` directly
├── Major version jump (e.g., v14 → v15)?
│ ├── Have custom apps?
│ │ ├── YES → Test on staging FIRST, check breaking changes
│ │ └── NO → Follow standard upgrade path
│ └── Multiple major versions (v14 → v16)?
│ └── ALWAYS upgrade one version at a time: v14 → v15 → v16
└── Production environment?
├── YES → ALWAYS test on staging clone first
└── NO → Proceed with standard upgrade
升级前检查清单
在进行任何主要版本升级之前,务必完成以下步骤:
- 完整备份 —
bench --site mysite backup --with-files - 在预发布环境中测试 — 将生产环境克隆到预发布 bench,并先在那里进行测试
- 检查破坏性变更 — 查看下方的破坏性变更部分
- 审核自定义应用 — 根据新版本的 API 变更检查自定义应用
- 检查 Python/Node 版本 — v15 要求 Node 18+;v16 要求 Node 24+、Python 3.14+
- 禁用调度器 —
bench --site mysite scheduler disable - 检查待处理作业 —
bench --site mysite ready-for-migration - 阅读发行说明 — 查看各版本的 GitHub 发行说明
标准升级流程
分步操作
# 1. Backup all sites
bench backup-all-sites
# 2. Switch to target version branch
bench switch-to-branch version-15 frappe erpnext
# 3. Update (pulls code, installs deps, builds, migrates)
bench update
# 4. Verify
bench --site mysite migrate # if not done by update
bench version # confirm versions
bench update 的执行顺序
- 备份所有站点
- 拉取所有应用的最新代码(
git pull) - 安装 Python 依赖项(
pip install) - 安装 Node 依赖项(
yarn install) - 构建静态资源(
bench build) - 在所有站点上运行迁移(
bench migrate) - 重启 bench 进程
v14 → v15 破坏性变更
环境要求
| 要求 | v14 | v15 |
|---|---|---|
| Node.js | v14+ | v18+ |
| Python 打包 | setup.py | pyproject.toml |
后端破坏性变更
- 已移除
db.set()— 请改用doc.db_set() - 已移除
db.sql()参数 — 不再接受as_utf8和formatted - Singles 的
db.set_value()— 请改用frappe.db.set_single_value() job_name已弃用 — 在enqueue()中使用job_id参数frappe.new_doc()参数 —parent_doc、parentfield、as_dict必须作为关键字参数传入frappe.get_installed_apps()— 不再接受sort或frappe_last参数- 方法覆盖顺序反转 — 现在优先使用最后一个覆盖项
- 时区函数重命名 —
convert_utc_to_user_timezone→convert_utc_to_system_timezone
前端破坏性变更
- Vue 2 → Vue 3 — 必须迁移所有 Vue 组件
- 已移除 window 全局变量 —
get_today→frappe.datetime.get_today,user→frappe.session.user - 客户端脚本中的
this— 不再支持访问局部作用域 - 图像延迟加载 — 将
website-image-lazy类替换为原生的loading="lazy"
安全变更
- 服务器脚本默认禁用 — 启用方式:
bench set-config -g server_script_enabled 1 - 新增“Desk User”角色 — 在 Desk 用户权限中取代“All”角色
- 已移除
currentsite.txt— 请使用bench use sitename或FRAPPE_SITE环境变量
已移除的功能
- 事件流已移至独立应用
- 已移除 Cordova 支持
- 已移除
setup.py(请使用pyproject.toml) - 已移除
--make_copy和--restore构建标志(请使用--hard-link)
完整列表请参阅 breaking-changes.md。
v15 → v16 破坏性变更
环境要求
| 要求 | v15 | v16 |
|---|---|---|
| Node.js | v18+ | v24+ |
| Python | 3.10+ | 3.14+ |
后端重大变更
- 默认排序顺序已更改 — 所有列表查询现在按
creation而非modified排序 has_permission钩子 — 必须显式返回True;不再接受Nonefrappe.get_doc(doctype, name, field=value)— 不再更新值- 文档钩子中的数据库提交 — 不再允许,以避免数据完整性问题
frappe.sendmail(now=True)— 不再隐式提交事务- Singles 的
db.get_value()— 现在返回正确类型,而非字符串 - 更改状态的方法必须使用 POST —
/api/method/logout、/api/method/upload_file等
已分离的模块(需单独安装)
- Energy Points →
frappe/eps - Newsletter →
frappe/newsletter - Backup Integrations →
frappe/offsite_backups - Blog →
frappe/blog
前端重大变更
- 报表/仪表板/页面 JS 以 IIFE 形式执行(不会污染全局作用域)
- Awesome Bar 已重新设计并移至侧边栏(
Cmd+K) - 已移除列表视图的右侧边栏
/apps端点已弃用;/app会重定向至/desk
配置变更
- 站点配置最多缓存一分钟(更改不会立即生效)
- Country 字段必须使用有效的 ISO 3166 ALPHA-2 代码
bench version输出格式已更改为 "plain"(旧格式请使用-f legacy)override_doctype钩子类必须继承被覆盖的类
完整列表请参见 breaking-changes.md。
补丁系统
补丁的工作方式
补丁是一次性数据迁移脚本,会在运行 bench migrate 时执行。补丁定义在各应用的 patches.txt 文件中。
patches.txt 格式 [v14+]
[pre_model_sync]
# Runs BEFORE schema sync — use for data prep
myapp.patches.v15_0.prepare_data_for_migration
[post_model_sync]
# Runs AFTER schema sync — use for data that needs new schema
myapp.patches.v15_0.migrate_data_to_new_fields
补丁执行规则
- 补丁按
patches.txt中定义的顺序运行 - 每个补丁只运行一次,执行记录在
__patches表中 - 要重新运行补丁,请追加日期注释:
myapp.patches.v15_0.fix #2025-03-20 - 一次性语句:
execute:frappe.delete_doc('Page', 'old_page', ignore_missing=True)
编写补丁
# myapp/patches/v15_0/migrate_field_data.py
import frappe
def execute():
# ALWAYS reload if you need the NEW schema
frappe.reload_doc("module_name", "doctype", "doctype_name")
# Perform data migration
frappe.db.sql("""
UPDATE `tabSales Invoice`
SET new_field = old_field
WHERE old_field IS NOT NULL
""")
调试卡住的补丁
# Check which patches have run
bench --site mysite console
>>> frappe.db.sql("SELECT * FROM __patches WHERE patch LIKE '%stuck_patch%'")
# Remove a patch record to force re-run
>>> frappe.db.sql("DELETE FROM __patches WHERE patch = 'myapp.patches.v15_0.broken_patch'")
>>> frappe.db.commit()
# Then re-run migrate
bench --site mysite migrate
回滚流程
立即回滚(数小时内)
# 1. Stop all processes
bench stop
# 2. Restore database from pre-upgrade backup
bench --site mysite restore /path/to/pre-upgrade-backup.sql.gz \
--with-public-files /path/to/files.tar \
--with-private-files /path/to/private-files.tar
# 3. Switch back to previous version branch
bench switch-to-branch version-14 frappe erpnext
# 4. Install old dependencies
bench setup requirements
# 5. Build old assets
bench build
# 6. Start bench
bench start # or: sudo bench restart (production)
回滚的重要规则
- 务必至少保留升级前备份 7 天
- 切勿在恢复到旧分支后运行
bench migrate——架构已经正确 - 务必同时恢复文件和数据库,否则文件引用可能会失效
- 切勿在用户已在升级后的版本中创建新数据后尝试回滚
Frappe Packages:在站点之间迁移自定义内容
Frappe Packages(v14+)是通过 UI 构建的轻量级应用,由 Custom Module Defs 打包而成,并以 .tar.gz 压缩包形式分发。对于标准 DocTypes 上的 Custom Fields、Property Setters 和 DocPerms,请改用 Fixtures。
快速参考:Package、Fixtures 与 App
| 机制 | 适用场景 | CLI 命令 |
|---|---|---|
| Package | 通过 UI 构建的 DocTypes、Scripts、Web Pages | 仅限 UI(Package Import/Release) |
| Fixtures | Custom Fields、Property Setters、DocPerms | bench --site mysite export-fixtures |
| Frappe App | 完整开发工作流、CI/CD、测试 | bench get-app、bench install-app |
Package 工作流(基于 UI)
- 创建 Package 文档 → 将 Custom Module Defs 分配给它
- 创建 Package Release → 将内容导出至
[bench]/sites/[site]/packages/,文件名为[package]-[version].tar.gz - 在目标站点创建 Package Import → 附加压缩包并勾选 Activate
- 系统会像应用迁移一样迁移数据;使用 Force 覆盖现有文件
Fixtures 工作流(基于 CLI)
# hooks.py — define what to export
fixtures = [
"Custom Field",
"Property Setter",
{"dt": "Client Script", "filters": [["module", "=", "My Module"]]}
]
# Export fixtures to JSON in your app
bench --site mysite export-fixtures --app myapp
# Fixtures auto-sync on: bench --site mysite migrate
切勿使用 Packages 修改标准/核心 DocTypes——请使用带有 Fixtures 的 Frappe App。
完整参考(包括决策树、限制和最佳实践)请参见 frappe-packages.md。
自定义应用兼容性检查
升级前,请审核每个自定义应用:
- 检查已弃用的 API — 搜索重大变更中列出的已移除函数
- 检查
setup.py— v15+ 必须迁移到pyproject.toml - 检查 Vue 组件 — v15+ 必须兼容 Vue 3
- 检查
patches.txt— 确保补丁使用[pre_model_sync]/[post_model_sync]部分 [v14+] - 检查 hooks.py — 确认没有使用已移除的钩子
- 运行测试 —
bench --site test_site run-tests --app myapp
决策树:原地升级还是全新安装
Choosing upgrade strategy:
├── Small site (< 10 GB database)?
│ └── In-place upgrade is usually fine
├── Large site (> 50 GB database)?
│ ├── Many custom apps? → Fresh install + data migration
│ └── Standard apps only? → In-place with extended downtime window
├── Skipping multiple versions (v13 → v15)?
│ └── ALWAYS fresh install — sequential upgrades are too risky
└── Critical production with zero-downtime requirement?
└── Fresh install on parallel server + DNS switch
版本差异摘要
| 功能 | v14 | v15 | v16 |
|---|---|---|---|
| Python 打包方式 | setup.py | pyproject.toml | pyproject.toml |
| Vue 版本 | Vue 2 | Vue 3 | Vue 3 |
| Node.js 最低版本 | v14 | v18 | v24 |
| Python 最低版本 | 3.8 | 3.10 | 3.14 |
| Server Scripts | 已启用 | 默认禁用 | 已禁用 |
| 默认排序 | 修改时间 | 修改时间 | 创建时间 |
| patches.txt 部分 | 是 | 是 | 是 |
| 工作区侧边栏 | 否 | 否 | 是 |
| 拆分的模块 | — | Event Streaming | Blog、Newsletter、EPS |
参考文件
| 文件 | 内容 |
|---|---|
| examples.md | 完整的升级工作流示例 |
| anti-patterns.md | 常见的升级错误及修复方法 |
| breaking-changes.md | 各版本的详细重大变更 |
| frappe-packages.md | 软件包、固定数据,以及在站点间迁移自定义项 |
评论
支持 Markdown