Skip to content

Natural Language Queries for Odoo Database: Complete Guide

DeployMonkey Team · March 22, 2026 13 min read

What Are Natural Language Queries for Odoo?

Instead of building reports in Odoo's UI, writing SQL, or navigating complex filter menus, you simply ask a question in plain English: "What were our top 10 customers by revenue last quarter?" An AI agent translates this into the appropriate Odoo ORM query or SQL statement, executes it against your database, and returns a formatted answer.

This is not a gimmick — it is a genuine productivity multiplier. Business users who would never write SQL or build Odoo reports can get answers in seconds. Managers get instant dashboards without waiting for IT. Finance teams can explore data without learning the reporting interface.

How It Works

The Translation Pipeline

  1. Natural language input — User asks: "Show me unpaid invoices over $5,000 grouped by customer"
  2. Intent extraction — LLM identifies: model=account.move, filter=payment_state != paid AND amount_total > 5000, group_by=partner_id
  3. ORM query generation — Agent generates the Odoo domain and read_group call
  4. Execution — Query runs against the database via XML-RPC with read-only access
  5. Formatting — Results returned as a table, chart description, or narrative summary
# What the agent generates internally:
result = models.execute_kw(db, uid, pwd,
    'account.move', 'read_group',
    [[('payment_state', '!=', 'paid'),
      ('amount_total', '>', 5000),
      ('move_type', '=', 'out_invoice')]],
    ['partner_id', 'amount_total'],
    ['partner_id'],
    orderby='amount_total desc')

Example Queries and Results

Sales Questions

  • "What is our total revenue this month?" → sale.order read_group with date filter
  • "Which salesperson has the highest average deal size?" → sale.order read_group grouped by user_id
  • "Show me all quotes pending for more than 7 days" → sale.order search with date_order filter
  • "Compare Q1 vs Q2 revenue by product category" → Two read_group calls with different date ranges

Inventory Questions

  • "What products are below reorder point?" → stock.warehouse.orderpoint vs current quantity
  • "Show me inventory value by warehouse" → stock.valuation.layer read_group
  • "Which items have not moved in 90 days?" → stock.move with date filter, exclude active items

Accounting Questions

  • "What is our accounts receivable aging?" → account.move.line with date buckets
  • "Show me our monthly expenses by category" → account.move.line read_group
  • "What is our cash position across all bank accounts?" → account.journal with balance computation

HR Questions

  • "How many employees joined this quarter?" → hr.employee search_count
  • "What is our leave balance by department?" → hr.leave.allocation read_group
  • "Show me overtime hours by team this month" → hr.attendance aggregation

Building the Analytics Agent

Architecture

┌────────────────────────┐
│  User Question          │
│  "Top 10 customers      │
│   by revenue Q3"        │
└──────────┬─────────────┘
           ▼
┌────────────────────────┐
│  LLM + Schema Context  │
│  Knows Odoo models,    │
│  field names, types    │
└──────────┬─────────────┘
           ▼
┌────────────────────────┐
│  Query Generator       │
│  Produces ORM domain   │
│  or read_group call    │
└──────────┬─────────────┘
           ▼
┌────────────────────────┐
│  Read-Only Execution   │
│  XML-RPC with limited  │
│  user permissions      │
└──────────┬─────────────┘
           ▼
┌────────────────────────┐
│  Result Formatter      │
│  Table, chart, or      │
│  narrative summary     │
└────────────────────────┘

Key Implementation Details

  • Read-only access — The analytics agent should NEVER have write access. Create a dedicated Odoo user with read-only permissions.
  • Schema context — Feed the LLM your model field definitions so it knows the correct field names and types
  • Query validation — Validate generated domains before execution to prevent injection
  • Result limits — Always set a limit on returned records (default: 100) to prevent memory issues
  • Caching — Cache frequent queries (daily revenue, monthly KPIs) to reduce database load

Common Challenges

Ambiguous Questions

"Show me sales" — which model? sale.order or account.move? What time period? The agent should ask clarifying questions when the query is ambiguous.

Computed Fields

Some Odoo fields are computed and not stored. The agent cannot use them in read_group or search domains. It must know which fields are stored and which need to be calculated from raw data.

Multi-Company Data

In multi-company setups, the agent must ensure queries respect company boundaries. Always include company_id filters.

Performance

Complex aggregation queries on large datasets can be slow. The agent should use read_group instead of reading individual records whenever possible, and warn users when queries touch large tables.

Security Considerations

  • Use a dedicated read-only Odoo user for the analytics agent
  • Restrict accessible models — not all data should be queryable (e.g., exclude user passwords, API keys)
  • Log all queries for audit purposes
  • Set query timeout to prevent long-running queries from affecting the server

Getting Started

To start querying your Odoo data with natural language, you need: a running Odoo instance (deploy on DeployMonkey for the easiest setup), an LLM with API access (Claude or GPT-4), and a connection script that bridges the LLM to Odoo's XML-RPC API. DeployMonkey's built-in AI agent already provides natural language data exploration as part of the platform.