精通 Odoo ORM 编程模式与性能优化
本技能深入解析 Odoo 对象关系映射(ORM)的核心模式,教你规范编写 search、browse、write 等调用,构建复杂域过滤器,以及杜绝常见的 N+1 查询性能陷阱。
为什么需要这个技能
Odoo 是基于 ORM 构建的 Python 应用框架,几乎不鼓励直接使用原始 SQL。不当的 ORM 写法(如循环中调用 search)会瞬间拖垮系统。掌握正确模式能让代码既安全又高效。
适用场景
- 需要编写自定义报表、自动化任务或复杂的业务逻辑脚本时。
- 开发 Odoo 模块,需要处理关联记录、计算字段或进行批量数据更新。
- 遇到查询过慢、批量操作卡顿或内存溢出等性能瓶颈问题。
- 在 Odoo SaaS 或自建服务器上都需要适用的场景。
核心工作流
- 激活技能:在对话中提及
@odoo-orm-expert并描述你的数据操作需求(如查询订单、更新客户)。 - 获取代码:接收包含解释的标准 Odoo ORM 代码片段,涵盖
domain过滤、related字段及上下文处理。 - 性能审查:上传现有代码片段,让 AI 检查是否存在循环查询、不必要的
sudo调用或对象序列化错误。
示例代码
示例 1:带域过滤的查询
# Find all confirmed sale orders for a specific customer, created this year
import datetime
start_of_year = datetime.date.today().replace(month=1, day=1).strftime('%Y-%m-%d')
orders = self.env['sale.order'].search([
('partner_id', '=', partner_id),
('state', '=', 'sale'),
('date_order', '>=', start_of_year),
], order='date_order desc', limit=50)
# Note: pass dates as 'YYYY-MM-DD' strings in domains,
# NOT as fields.Date objects — the ORM serializes them correctly.
示例 2:计算字段优化
total_order_count = fields.Integer(
string='Total Orders',
compute='_compute_total_order_count',
store=True
)
@api.depends('sale_order_ids')
def _compute_total_order_count(self):
for record in self:
record.total_order_count = len(record.sale_order_ids)
示例 3:安全的批量写入(避免 N+1)
# ✅ GOOD: One query for all records
partners = self.env['res.partner'].search([('country_id', '=', False)])
partners.write({'country_id': self.env.ref('base.us').id})
# ❌ BAD: Triggers a separate query per record
for partner in partners:
partner.country_id = self.env.ref('base.us').id
最佳实践与限制
- ✅ 要做:使用
mapped()、filtered()和sorted()操作记录集,代替纯 Python 循环。 - ✅ 要做:仅在理解安全影响时谨慎使用
sudo()。 - ✅ 要做:需要计数时使用
search_count(),避免先search再取len。 - ❌ 别做:在循环内调用
search(),这是性能杀手。 - ❌ 别做:除非必要,否则不要混用原始 SQL 和 ORM。
- ❌ 别做:将 Python
datetime对象直接放入域,必须转换为字符串。
技能局限说明:
- 不包含对
cr.execute()原始 SQL 的深入覆盖。 - 不处理大规模存储计算字段的分区策略。
- 不支持瞬态模型或向导模式。
- SaaS 与自建版在配置覆盖下行为可能略有不同。
下载和安装
下载 odoo-orm-expert 中文版 Skill ZIP
解压后将目录放入你的 AI 工具 skills 文件夹,重启工具后即可使用。具体路径参考内附的使用文档。
你可能还需要
暂无推荐