Skip to content

Conversation

@SilvioC2C
Copy link
Contributor

No description provided.

Copy link
Contributor

@legalsylvain legalsylvain left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

interesting feature.

Could you share statistics on performance improvements, if you have any.

@SilvioC2C SilvioC2C force-pushed the 17.0-ADD-base_write_diff branch from a54ca05 to dc7c272 Compare November 21, 2025 09:59
@SilvioC2C
Copy link
Contributor Author

SilvioC2C commented Nov 21, 2025

@legalsylvain hello 👋

To be honest, I don't have stats about performance diffs between the usage of write_diff() against write().

However, the features included in this module were before included in a custom module we've been using in a production environment (for a few months now) within this context:

  • Odoo needs to receive data from an external service, and the external service always sends all fields' values to Odoo
  • when importing these values, even if the new values are exactly the same as the old ones, Odoo would trigger lots of recomputations (eg: when sending data about SO lines' amounts), and lots of registry cache invalidations would occur (see the product.product.write() override in USAGE.md)
  • with the features now included in this module, we were able to prevent all that from happening and improve the overall performances of each import execution

@SilvioC2C SilvioC2C force-pushed the 17.0-ADD-base_write_diff branch from dc7c272 to a3a64a7 Compare November 21, 2025 10:55
Copy link
Contributor

@yankinmax yankinmax left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @SilvioC2C , great work!



def post_load_hook():
patch_base_model_write()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIK post_load is executed globally (meant for server wide modules) and so in a multi-tenant deployment it would affect databases without this module installed.

AFAICS this is only needed for the context-based usage. TBH I'd drop it and keep only the explicit write_diff method usage (KISS)

Alternatively, if you want to keep it, I'd explore _register_hook / _unregister_hook. This is the mechanism used in the core base_automation module

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense, thanks! I'll update the module accordingly.


from odoo.addons.web.models.models import RecordSnapshot

original_write = models.BaseModel.write
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will not respect other modules doing the same thing, cause the original_write is evaluated at import time.

For example, this probably breaks the base_automation module hooks

You need to follow the pattern used in base_automation, that builds the patch method on the fly and uses write.origin(..) to call the original method

@SilvioC2C SilvioC2C force-pushed the 17.0-ADD-base_write_diff branch from 3eb249c to b301baa Compare November 27, 2025 15:04
@SilvioC2C
Copy link
Contributor Author

@ivantodorovich mind taking another look? It should be fine now

@ivantodorovich
Copy link
Contributor

IMO it's still wrong. In a multi-tenant deployment you'd have a race condition with several registries setting/unsetting _origin.

We need to patch the registry's loaded model, not the BaseModel definition itself.

For that the method needs to be created on-the-fly, and patched like this: https://github.com/odoo/odoo/blob/69828835c926485ec80ed92e14dd11fbc6c1caaa/addons/base_automation/models/base_automation.py#L786-L811

@ivantodorovich
Copy link
Contributor

TBH I'm not even sure you need this, compared to a regular write override 🤔
With _register_hook you're override would be the first to execute, cause the method would be added to the top of the MRO
With a regular write override on base you're override would likely be the last one to execute (except other modules also try this, then it depends on their loading order)

I thought you wanted the first scenario, cause that would make sense logically for me. ..but maybe I'm wrong, and you wanted the second one ?
In this case a simple override would be fine -- cause it's very very unlikely other modules try to override the base model write method to ADD new values.

@SilvioC2C SilvioC2C force-pushed the 17.0-ADD-base_write_diff branch from b301baa to 2a787d4 Compare November 27, 2025 16:18
@SilvioC2C
Copy link
Contributor Author

@ivantodorovich you're right, a write() override was enough, I've updated the code accordingly

@OCA-git-bot
Copy link
Contributor

This PR has the approved label and has been created more than 5 days ago. It should therefore be ready to merge by a maintainer (or a PSC member if the concerned addon has no declared maintainer). 🤖

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants