Difference Between read(), search_read(), and search() in Odoo


✅ Purpose of Each


Method

Purpose

read()

Reads specified fields from known record IDs.

search()

Finds records using domain filters; returns full recordset.

search_read()

Combines search() + read(); returns a list of dictionaries (raw data).


📌 Realistic Odoo Examples


1. read() – Read fields from known IDs


partners = self.env['res.partner'].browse([1, 2, 3])

data = partners.read(['name', 'email'])

🔹 Returns:

[{'id': 1, 'name': 'ABC Corp', 'email': 'abc@example.com'}, ...]


  • Does not perform a search.

  • Ideal when you already have IDs (e.g., from foreign keys or other logic).
  • Lightweight and efficient for just fetching specific fields.


2. search() – Search with domain, returns full recordset


partners = self.env['res.partner'].search([('customer_rank', '>', 0)], limit=10)

for partner in partners:

    print(partner.name, partner.email)


  • Returns recordset, not dictionary.
  • Triggers all ORM features: computed fields, related fields, prefetching.
  • Suitable when you need full object access or will use advanced logic.

3. search_read() – Optimized for raw data read


data = self.env['res.partner'].search_read(

    [('customer_rank', '>', 0)],

    fields=['name', 'email'],

    limit=10

)

🔹 Returns:

[{'id': 1, 'name': 'ABC Corp', 'email': 'abc@example.com'}, ...]


  • Very efficient for frontend calls, reports, or lightweight API responses.
  • Returns dictionary (not a recordset) → you cannot call .method() on result.


⚙️ Comparison Summary


Feature

read()

search()

search_read()

Input Type

List of IDs

Domain

Domain

Output Type

List of dicts

Recordset

List of dicts

Fetches Specific Fields

✅ Yes (fields param)

✅ (all by default, can be lazy)

✅ Yes (fields param)

Lightweight

✅ Yes

❌ Heavier (full records)

✅ Yes

Use When

IDs are known

You need recordset/methods

You need raw data efficiently

API/Frontend Use

🚫 Not ideal

🚫 Not ideal

✅ Preferred


🧠 Final Tips

  • Use search_read() for read-only API responses or UI lists.
  • Use search() if you need to operate on records (e.g., call methods).
  • Use read() when you already have record IDs and need selected fields.