Sunday, February 23, 2025
1 change · master
Enhancements to existing features
This update improves how Odoo creates new records by keeping internal data in sync and avoiding unnecessary database lookups. Businesses may see better performance and fewer hidden consistency issues in everyday operations that create records, such as contacts, mailings, and other system data.
Original PR description
Bunch of fixes/improvements to simplify the logic and improve the performance of method `_create()`. #### [FIX] core: fix _create() cache consistency When a record is created, the cache is set with a…
Bunch of fixes/improvements to simplify the logic and improve the performance of method `_create()`.
#### [FIX] core: fix _create() cache consistency
When a record is created, the cache is set with a falsy value for each stored field that is not explicitly included in the INSERT values. The specific falsy value used depends on the field type and is determined by the call convert_to_cache(False).
For instance, if we don't assign a boolean field upon create(), the database column value of the row is `NULL` (we don't use database default values), but we put `False` in cache instead of `None`!
This complexity is unnecessary and creates inconsistencies between the cache and the database. Since database values are not converted during _fetch_query(), the cache value after calling create() should be also equal to the value coming out of the database.
#### [IMP] core: populate cache for non-inserted store compute fields
Currently, in _create(), unassigned stored computed fields are simply not assigned in cache. This difference with other fields is unjustified and may result in some additional SQL queries for retrieving those fields' values. This additional query is systematic when the field's compute method explicitly uses the field's current value.
The fix simply consists in not treating those fields differently from other fields. Furthermore, this change is necessary for binary fields, which depend on the cache for the shortcut in Binary.write().
#### [REF] core: simplify cache filling in _create
The current code in _create() forces the cache to None for related fields without a column_type (x2many fields or binary fields stored in attachments). It is actually useless to do this, as those fields are actually invalidated by modified() later inside _create().
Remove this part of the code for the sake of simplicity and efficiency.
#### [IMP] core: don't invalidate empty x2many in _create()
When we create a record with an explicit falsy value for an x2many field (either with `False` or a empty list), at the end of _create() we invalidate the cache for these fields. It means that reading them after the creation of the record generates a useless SQL query:
```
record = create({'line_ids': []})
record.line_ids # generate a query and return an empty recordset
```
Fix this behavior for efficiency because we know that no records can target the records just created. In the code, this means dropping the temporary variable 'cachetoclear' and the related comment that doesn't make sense. We also need to add a check before forcing the cache to an empty tuple for x2many fields since it is valid only for store x2many fields.
Some changes has to be made in the business code when there many2many that actually use a Odoo model table. In such a case, the ORM stores an incorrect value (empty value) in cache for the field. However, that value was accidentally invalidated by some incorrect mechanism, and the cache inconsistency was hidden by chance. It now has to be fixed explicitly by invalidating the field.
### Overall performance improvements
Those changes imply a small improvement on runbot, by reducing the number of queries by about 1.8%. At install, enterprise:
```
Before: 457983 queries (+2569122 extra)
After: 453668 queries (+2522415 extra)
```