c2c-oerpscenario team mailing list archive
-
c2c-oerpscenario team
-
Mailing list archive
-
Message #00020
[Bug 659021] Re: inherit bug on orm : useless call of write method making openerp slow
Hello Sébastien,
It has been fixed by revision 2141
jvo@xxxxxxxxxxx-20101012192045-7zx1tgznp3greksl authored to you.
Thanks.
** Changed in: openobject-server
Status: Confirmed => Fix Released
--
inherit bug on orm : useless call of write method making openerp slow
https://bugs.launchpad.net/bugs/659021
You received this bug notification because you are a member of C2C
OERPScenario, which is subscribed to OpenERP OpenObject.
Status in OpenObject Server: Fix Released
Bug description:
Hi
I am working on product_variant_multi for on of my customer, and I discover an bug.
(here is the branch, I will merge it soon : https://code.launchpad.net/~akretion-team/openobject-addons/product_variant_multi_improve)
What is product_variant_multi:
OpenERP is already supporting a product variants at the core level. But
without product_variant_multi, variants are only mono-axial. OpenERP indeed uses the product.tempate
as the model object and the product.variant as the instance variant.
Problem:
When I save a product_product (because I change the field "default_code", note that this field is an product_product field), the write method is also apply on the product_template. Indeed if the write method is called for product_product it will be always called for the product_template WITHOUT checking if a field of product_template have been changed.
In 95% of case this is not a problem because the write method is called with the parameter vals={}. So it's just an useless call.
But In my case I have a field on product_product (the field in variants) which is a function field stored.
Here is the definition of the field :
'variants': fields.function(_variant_name_get, method=True, type='char', size=128, string='Variants', readonly=True,
store={
'product.variant.dimension.type': (_get_products_from_dimension, None, 10),
'product.product': (_get_products_from_product, ['product_tmpl_id'], 10),
'product.template': (_get_products_from_product_template, ['variant_model_name', 'variant_model_name_separator'], 10),
}),
As you can see this field will be automatically re-calculated if there is any change on :
- one of the field of the object 'product.variant.dimension.type'
- the field 'product_tmpl_id' of the object product.product
- the fields 'variant_model_name' or 'variant_model_name_separator' of the product.template.
The BIG problem is that this useless call of the write function with vals = {}, will lask for re-calculating of the stored field 'variants'.
We can easily resolve this bug by checking if vals is empty before calling the write method.
CODE: /bin/osv/orm.py
BEFORE
for table in self._inherits:
col = self._inherits[table]
query = 'SELECT DISTINCT "%s" FROM "%s" WHERE id IN %%s' % (col, self._table)
nids = []
for i in range(0, len(ids), cr.IN_MAX):
sub_ids = ids[i:i+cr.IN_MAX]
cr.execute(query, (tuple(sub_ids),))
nids.extend([x[0] for x in cr.fetchall()])
v = {}
for val in updend:
if self._inherit_fields[val][0] == table:
v[val] = vals[val]
self.pool.get(table).write(cr, user, nids, v, context)
AFTER :
for table in self._inherits:
col = self._inherits[table]
query = 'SELECT DISTINCT "%s" FROM "%s" WHERE id IN %%s' % (col, self._table)
nids = []
for i in range(0, len(ids), cr.IN_MAX):
sub_ids = ids[i:i+cr.IN_MAX]
cr.execute(query, (tuple(sub_ids),))
nids.extend([x[0] for x in cr.fetchall()])
v = {}
for val in updend:
if self._inherit_fields[val][0] == table:
v[val] = vals[val]
if v: #<===HERE check if where is something to write!!!
self.pool.get(table).write(cr, user, nids, v, context)
For information when you have a lot of variant (6000 variants for one template) just saving a product (without this patch) will require more than 5s on a my computer (core i5, 6 Go ram...)!!!
I send a path
Thanks you