Odoo 18模块迁移后出现TypeError: SQL与str无法相加错误
Odoo 18模块迁移:SQL与字符串拼接类型错误解决
问题场景
将Odoo 17中正常运行的模块迁移至Odoo 18后,安装时触发以下错误:
TypeError: unsupported operand type(s) for +: 'SQL' and 'str'
原Odoo 17代码片段:
def _select(self): return super()._select() + ", sol.lot_id as location_lot_id" def _group_by(self): return super()._group_by() + " , sol.lot_id, "
尝试用odoo.tools.sql.SQL包装字符串后仍报错的代码:
from odoo import fields, models from odoo.tools.sql import SQL class RentalSchedule(models.Model): _inherit = "sale.rental.schedule" location_lot_id = fields.Many2one( 'stock.lot', 'Lot/serial number', readonly=True ) def _select(self): return super()._select() + SQL("sol.lot_id AS location_lot_id") def _group_by(self): return super()._group_by() + SQL("sol.lot_id")
错误原因
Odoo 18对ORM查询构建逻辑进行了升级,sale.rental.schedule的_select和_group_by方法返回的是SQL对象,而非Odoo 17中的字符串类型。直接使用+运算符拼接SQL对象与字符串,或拼接时未保证两边类型统一,会触发类型不兼容错误。
解决方案
确保所有拼接的查询片段都为SQL对象,同时注意SQL语法的合法性(避免多余的逗号、空格),可采用两种方式实现:
方式1:统一用SQL包装片段后拼接
from odoo import fields, models from odoo.tools.sql import SQL class RentalSchedule(models.Model): _inherit = "sale.rental.schedule" location_lot_id = fields.Many2one( 'stock.lot', 'Lot/serial number', readonly=True ) def _select(self): # 给新增字段片段添加逗号前缀,确保SQL语法正确 return super()._select() + SQL(", sol.lot_id AS location_lot_id") def _group_by(self): # 去掉原代码末尾多余的逗号和空格,保证拼接后SQL合法 return super()._group_by() + SQL(", sol.lot_id")
方式2:使用SQL对象的add方法(更规范)
from odoo import fields, models from odoo.tools.sql import SQL class RentalSchedule(models.Model): _inherit = "sale.rental.schedule" location_lot_id = fields.Many2one( 'stock.lot', 'Lot/serial number', readonly=True ) def _select(self): return super()._select().add(SQL(", sol.lot_id AS location_lot_id")) def _group_by(self): return super()._group_by().add(SQL(", sol.lot_id"))
注意事项
- 检查父类方法返回类型:Odoo 18中大量底层查询构建方法已改为返回SQL对象,迁移时需确认继承方法的返回类型
- 保证SQL语法合法:拼接时注意字段间的逗号分隔,避免多余符号导致SQL执行错误
- 统一类型处理:所有拼接的查询片段必须为SQL对象,禁止混合字符串与SQL对象操作
内容的提问来源于stack exchange,提问作者user29412116
相关产品推荐
相关产品推荐

