升级脚本¶
升级脚本是一个 Python 文件,其中包含一个名为 migrate() 的函数,升级过程会在更新模块期间调用该函数。
- migrate(cr, version)¶
- 参数
cr (
Cursor) – current database cursorversion (str) – installed version of the module
通常,该函数会执行一条或多条 SQL 查询,也可以访问 Odoo 的 ORM 以及 升级实用工具。
编写升级脚本¶
升级脚本遵循特定的目录树结构和命名规范,该规范决定了脚本何时执行。
升级脚本路径的结构为 $module/migrations/$version/pre,post,end-*.py,其中 $module 是脚本将要运行的模块,$version 是模块的完整版本(包括 Odoo 的大版本号和模块的小版本号),{pre|post|end}-*.py 是需要执行的文件。文件名将决定脚本在该模块和版本中执行的 阶段 和顺序。
Note
从 Odoo 13 开始,升级脚本的顶层目录也可以命名为 upgrades。推荐使用这一命名,因为其含义更加准确:migrate 容易与 迁出 Odoo 混淆。因此 $module/upgrades/$version/ 也是有效的。
Note
升级脚本只在模块被更新时执行。因此,$version 目录中设置的模块小版本号必须高于模块已安装的版本,并且等于或低于模块更新后的版本。
Example
自定义模块 awesome_partner 在 Odoo 17 上升级到版本 2.0 时升级脚本的目录结构。
awesome_partner/
|-- migrations/
| |-- 17.0.2.0/
| | |-- pre-exclamation.py
两个升级脚本示例,其中 pre-exclamation.py 文件的内容是在合作伙伴名称末尾添加”!”:
import logging
_logger = logging.getLogger(__name__)
def migrate(cr, version):
cr.execute("UPDATE res_partner SET name = name || '!'")
_logger.info("Updated %s partners", cr.rowcount)
import logging
from odoo.upgrade import util
_logger = logging.getLogger(__name__)
def migrate(cr, version):
env = util.env(cr)
partners = env["res.partner"].search([])
for partner in partners:
partner.name += "!"
_logger.info("Updated %s partners", len(partners))
请注意,在第二个示例中,脚本借助 升级实用工具 来访问 ORM。请查阅该文档以进一步了解这个程序库。
升级脚本的阶段¶
对于每个模块的每个版本,升级过程由三个阶段组成:
pre 阶段,在模块加载之前执行。
post 阶段,在模块及其依赖被加载并更新之后执行。
end 阶段,在该版本的所有模块都已加载并更新之后执行。
升级脚本按文件名的第一部分归入相应的阶段。在每个阶段内,文件按字典序依次执行。
同一模块同一版本示例脚本的执行顺序
pre-10-do_something.pypre-20-something_else.pypost-do_something.pypost-something.pyend-01-migrate.pyend-migrate.py