本文介绍了一些Odoo模块版本升级的常用技巧和脚本。这些脚本能大大的提高模块升级的效率。 原文请参见:Module Migration
代码回顾
下列的命令用来评估模块版本迁移大致的工作量,执行命令后可以一次显示所涉模块的所有源码。
# 查看所有源码
find . -iname "*.py" -or -iname "*.xml" -or -iname "*.csv" -or -iname "*.yml" -or -iname "*.js" -or -iname "*.rst" -or -iname "*.md" | xargs tail -n +1 | less
# 查看所有不包含文档的源码
find . -iname "*.py" -or -iname "*.xml" -or -iname "*.csv" -or -iname "*.yml" -or -iname "*.js" | xargs tail -n +1 | less
关闭不迁移的模块
# (从上游版本库中创建一个新的分支)
# 将所有模块设置成不可安装(non-installable)
find . -type f -name __openerp__.py -or -name __manifest__.py | xargs sed -i 's/"installable": True/"installable": False/'
find . -type f -name __openerp__.py -or -name __manifest__.py | xargs sed -i "s/'installable': True/'installable': False/"
# 检查没有``installable``标签的模块描述文件
find . -type f -name __openerp__.py -or -name __manifest__.py | xargs grep -L "installable.: "
# (如果发现了这些文件则手动编辑使其installable=False)
# 准备提交
git add .
# 检查diff
git diff --cached
git commit -m "[PORT] mark unported modules as non-installable"
# (推送到上游版本库 "git push" 并在github上请求合并)
代码迁移到新的API
自动替换
# 所有的Import替换
# 替换 osv, orm
find . -type f -name '*.py' | xargs sed -i 's/from openerp.osv import orm$/from odoo import models/g'
find . -type f -name '*.py' | xargs sed -i 's/from openerp.models.orm import Model$/from odoo.models import Model/g' find . -type f -name '*.py' | xargs sed -i 's/osv.osv_memory/models.TransientModel/g'
find . -type f -name '*.py' | xargs sed -i 's/osv.osv/models.Model/g'
find . -type f -name '*.py' | xargs sed -i 's/osv.except_osv/UserError/g'
find . -type f -name '*.py' | xargs sed -i 's/osv\./models./g'
find . -type f -name '*.py' | xargs sed -i 's/\<orm\./models./g'
find . -type f -name '*.py' | xargs sed -i 's/\(import .*\), osv/\1, models/g'
find . -type f -name '*.py' | xargs sed -i 's/\(import .*\)osv, /\1models, /g'
find . -type f -name '*.py' | xargs sed -i 's/\(import .*\)osv/\1models/g'
find . -type f -name '*.py' | xargs sed -i 's/\(import .*\), orm/\1/g'
find . -type f -name '*.py' | xargs sed -i 's/\(import .*\)orm, /\1/g'
find . -type f -name '*.py' | xargs sed -i 's/^.*import orm$//g'
find . -type f -name '*.py' | xargs sed -i 's/openerp.osv/openerp/g'
# 替换 http import
find . -type f -name '*.py' | xargs sed -i 's/from openerp.addons.web import http/from odoo import http/g'
find . -type f -name '*.py' | xargs sed -i 's/openerp.addons.web.http/odoo.http/g'
find . -type f -name '*.py' | xargs sed -i 's/openerp.http/odoo.http/g'
# 替换 odoo
# 导入路径替换。否则会有下面的错误:
# AttributeError: 'module' object has no attribute 'session_dir'
find . -type f -name '*.py' | xargs sed -i 's/openerp.tools.config/odoo.tools.config/g'
# 全局替换openerp为odoo
find . -type f -name '*.py' | xargs sed -i 's/from openerp/from odoo/g'
# 字段
# 更新字段
# (multiline: http://stackoverflow.com/questions/1251999/how-can-i-replace-a-newline-n-using-sed/7697604#7697604 )
# 删除 `_columns` 属性
find . -type f -name '*.py' | xargs perl -i -p0e 's/ _columns = {(.*?)\n }/$1\n/gs'
# 计算字段
find . -type f -name '*.py' | xargs sed -i 's/fields.function(\(.*\) \(["\x27][^,]*\)/fields.function(\1 string=\2/g'
find . -type f -name '*.py' | xargs sed -i 's/fields.function(\(.*\) multi=[^,)]*/fields.function(\1/g'
find . -type f -name '*.py' | xargs sed -i 's/fields.function(\([^,]*\)\(.*\)type=.\([2a-z]*\)["\x27]/fields.\3(compute="\1"\2/g'
find . -type f -name '*.py' | xargs sed -i 's/fields.many2one(\(.*\)obj=\([^,]*\)/fields.many2one(\2, \1/g'
find . -type f -name '*.py' | xargs sed -i 's/,[ ]*,/,/g'
find . -type f -name '*.py' | xargs sed -i 's/,[ ]*,/,/g'
find . -type f -name '*.py' | xargs sed -i 's/,[ ]*,/,/g'
# 替换 fields
find . -type f -name '*.py' | xargs perl -i -p0e 's/ _columns = {(.*?) }/$1/gs'
find . -type f -name '*.py' | xargs sed -i 's/fields\.\(.\)/fields.\u\1/g'
find . -type f -name '*.py' | xargs sed -i 's/ [\x27"]\(.*\)[\x27"].*:.*\(fields.*\),$/\1 = \2/g'
# 更名 attributes
find . -type f -name '*.py' | xargs sed -i 's/select=/index=/g'
find . -type f -name '*.py' | xargs sed -i 's/digits_compute=/digits=/g'
半自动替换
我们推荐在提交了上述修改之后,使用下面的命令来检查并手工做更新。
# pool -> env
find . -type f -name '*.py' | xargs sed -i 's/self.pool/self.env/g'
# 去除 cr, uid
find . -type f -name '*.py' | xargs sed -i 's/(cr, [^,]*, /(/g'
find . -type f -name '*.py' | xargs sed -i 's/(self, cr, [^,]*, ids/(self/g'
find . -type f -name '*.py' | xargs sed -i 's/(self, cr, uid, /(self, /g'
find . -type f -name '*.py' | xargs sed -i 's/, context=[^,)]*//g'
find . -type f -name '*.py' | xargs sed -i 's/self.env.get(\([^)]*\))/self.env[\1]/g'
# res_config.py
find . -type f -name 'res_config.py' | xargs sed -i 's/\(def get_default_.*\)(self)/\1(self, fields)/g'
10.0+ 更新
# 将``__openerp__.py``更名为``__manifest__.py``
find . -type f -name __openerp__.py -exec rename 's/__openerp__.py/__manifest__.py/' '{}' \;
11.0+ 更新
# ir.config_parameter -- 在``get_param``/``set_param``前添加``sudo()``
find . -type f -name '*.py' | xargs perl -i -p0e 's/(?<!sudo\(\)\.)(get_param|set_param)/sudo().$1/g'
引用名的迁移
9.0-
→ 10.0+
# menu_hr_configuration
find . -type f -name '*.xml' | xargs sed -i 's/menu_hr_configuration/menu_human_resources_configuration/g'
# base.group_hr
find . -type f -name '*.csv' -o -name '*.py' -o -name '*.xml' | xargs sed -i 's/base.group_hr/hr.group_hr/g'
# website.salesteam_website_sales
find . -type f -name '*.csv' -o -name '*.py' -o -name '*.xml' | xargs sed -i 's/website.salesteam_website_sales/sales_team.salesteam_website_sales/g'
# base.group_sale_salesman
find . -type f -name '*.csv' -o -name '*.py' -o -name '*.xml' | xargs sed -i 's/base.group_sale_salesman/sales_team.group_sale_salesman/g'
# product.prod_config_main
find . -type f -name '*.xml' | xargs sed -i 's/product.prod_config_main/sale.prod_config_main/g'
10.0-
→ 11.0+
# mixins in js
find . -type f -name '*.js' | xargs sed -i 's/core\.mixins/require("web.mixins")/g'
# 11.0 没有 website.config.settings
find . -type f -name '*.py' -o -iname '*.xml' | xargs sed -i 's/website\.config\.settings/res.config.settings/g'
# page="True" 不再使用了
find . -type f -name '*.xml' | xargs sed -i 's/ page="True"//g'
迁移到python3
# urlparse
find . -type f -name '*.py' | xargs sed -i 's/import urlparse/import urllib.parse as urlparse/g'
find . -type f -name '*.py' | xargs sed -i 's/from urlparse/from urllib.parse/g'