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.