** Branch linked: lp:openobject-server/5.0 -- 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 _______________________________________________ Mailing list: https://launchpad.net/~c2c-oerpscenario Post to : [email protected] Unsubscribe : https://launchpad.net/~c2c-oerpscenario More help : https://help.launchpad.net/ListHelp

