mcpField
O
odoo-orm-expert

odoo-orm-expert

github.com/sickn33Development48.7k82 installsUpdated today
Repository

About odoo-orm-expert

An instructional skill for Odoo ORM work, aimed at developers writing data operations, domain filters, and computed fields or diagnosing query performance. It provides idiomatic code guidance and highlights batching, access control, and common pitfalls such as searches inside loops.

Key features

  1. 01Guidance for record CRUD operations
  2. 02Build domain filters
  3. 03Implement computed and related fields
  4. 04Review ORM performance patterns
  5. 05Avoid N+1 query pitfalls
  6. 06Consider access and record scope

Use cases

  1. 01Write Odoo search and write methods
  2. 02Filter records for views or server actions
  3. 03Optimize bulk record updates
  4. 04Investigate slow ORM queries

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/sickn33/agentic-awesome-skills --skill odoo-orm-expert

After installing, type/odoo-orm-expertin Claude Code to confirm it loaded.

Details

From the project README

Odoo ORM Expert

Overview

This skill teaches you Odoo's Object Relational Mapper (ORM) in depth. It covers reading/writing records, building domain filters, working with relational fields, and avoiding common performance pitfalls like N+1 queries.

When to Use This Skill

  • Writing search(), browse(), create(), write(), or unlink() calls.
  • Building complex domain filters for views or server actions.
  • Implementing computed, stored, and related fields.
  • Debugging slow queries or optimizing bulk operations.

How It Works

  1. Activate: Mention @odoo-orm-expert and describe what data operation you need.
  2. Get Code: Receive correct, idiomatic Odoo ORM code with explanations.
  3. Optimize: Ask for performance review on existing ORM code.

Examples

Example 1: Search with Domain Filters
# Find up to 50 confirmed sale orders for a specific customer dated this UTC year
import datetime

year = datetime.datetime.now(datetime.timezone.utc).year
start_of_year = datetime.datetime(year, 1, 1)  # Odoo stores naive UTC datetimes
start_of_next_year = datetime.datetime(year + 1, 1, 1)

orders = self.env['sale.order'].search([
    ('partner_id', '=', partner_id),
    ('state', '=', 'sale'),
    ('date_order', '>=', start_of_year),
    ('date_order', '<', start_of_next_year),
], order='date_order desc', limit=50)

# date_order is a Datetime field. For precise business-year boundaries,
# construct UTC datetime bounds from the intended business timezone;
# this example uses the UTC calendar year.
Example 2: Computed Field
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)
Example 3: Safe Bulk Write (avoid N+1)
# Batch writes reduce repeated calls, but can trigger additional compute/tracking queries
partners = self.env['res.partner'].browse(approved_partner_ids).exists()  # Explicit scoped IDs
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

Best Practices

  • ✅ Do: Use mapped(), filtered(), and sorted() on recordsets instead of Python loops.
  • ✅ Do: Use sudo() sparingly and only when you understand the security implications.
  • ✅ Do: Prefer search_count() over len(search(...)) when you only need a count.
  • ✅ Do: Use with_context(...) to pass context values cleanly rather than modifying self.env.context directly.
  • ❌ Don't: Call search() inside a loop — this is the #1 Odoo performance killer.
  • ❌ Don't: Use raw SQL unless absolutely necessary; use ORM for all standard operations.
  • ✅ Do: Match values to the field type: Date uses dates or server date strings; Datetime uses datetimes or server datetime strings. Python date/datetime objects are supported; do not truncate a datetime to a date or mix the two types when comparing. See the Odoo ORM date/time guidance.

Limitations

  • Does not cover cr.execute() raw SQL patterns in depth — use the Odoo performance tuner skill for SQL-level optimization.
  • Stored computed fields can cause significant write overhead at scale; this skill does not cover partitioning strategies.
  • Does not cover transient models (models.TransientModel) or wizard patterns.
  • ORM behavior can differ slightly between Odoo SaaS and On-Premise due to config overrides.

Examples are model-method fragments requiring imports, record definitions and authorized scope. Do not infer missing country data means US; write only confirmed values to selected records. sudo() bypasses access rules and requires a justified boundary. Batch operations do not guarantee one SQL query, and mapped/filtered may load large recordsets; profile actual query counts and test record-rule/multi-company isolation.

Comments

Markdown supported