openerp-india team mailing list archive
-
openerp-india team
-
Mailing list archive
-
Message #16684
[Bug 769632] Re: Removing Administrator employee record causes future updates of hr module to fail
** Branch linked: lp:~therp-nl/openupgrade-
addons/6.1-lp769632-purge_ir_model_data_from_deleted_admin_employee
--
You received this bug notification because you are a member of OpenERP
Indian Team, which is subscribed to OpenERP Addons.
https://bugs.launchpad.net/bugs/769632
Title:
Removing Administrator employee record causes future updates of hr
module to fail
Status in OpenERP Addons (modules):
Fix Released
Status in OpenUpgrade Addons:
In Progress
Bug description:
I am using openerp ver. 6.0.2 on ubuntu 10.10
To reproduce:
1. Create a new database with no demo data
2. Install the Human Resources application with no optional hr_* modules selected
3. Open newly created database
4. Navigate Menu -> Human Resources -> Human Resources -> Employees
5. Delete the Administrator record
6. Restart the openerp server with command line option --update=hr
7. Try to create a new employee record
Error:
[2011-04-23 23:26:35,063][test_hr] ERROR:tools.convert.xml_import:Parse error in /usr/share/pyshared/openerp-server/addons/hr/hr_data.xml:19:
<record id="employee" model="hr.employee">
<field name="name">Administrator</field>
<field name="user_id" ref="base.user_root"/>
</record>
Traceback (most recent call last):
File "/usr/share/pyshared/openerp-server/tools/convert.py", line 865, in parse
self._tags[rec.tag](self.cr, rec, n)
File "/usr/share/pyshared/openerp-server/tools/convert.py", line 832, in _tag_record
id = self.pool.get('ir.model.data')._update(cr, self.uid, rec_model, self.module, res, rec_id or False, not self.isnoupdate(data_node), noupdate=self.isnoupdate(data_node), mode=self.mode, context=rec_context )
File "/usr/share/pyshared/openerp-server/addons/base/ir/ir_model.py", line 710, in _update
},context=context)
File "/usr/share/pyshared/openerp-server/osv/orm.py", line 3647, in create
cr.execute('insert into "'+self._table+'" (id'+upd0+") values ("+str(id_new)+upd1+')', tuple(upd2))
File "/usr/share/pyshared/openerp-server/sql_db.py", line 78, in wrapper
return f(self, *args, **kwargs)
File "/usr/share/pyshared/openerp-server/sql_db.py", line 131, in execute
res = self._obj.execute(query, params)
IntegrityError: duplicate key value violates unique constraint "ir_model_data_module_name_uniq"
Analysis:
The record that causes the error is the Administrator employee record in addons/hr/hr_data.xml. After the initial database creation the relevant records in ir_model_data look like this:
id | name | module | model | res_id
------+-------------------------------------------+-----------+-------------------------+--------
2170 | employee | hr | hr.employee | 1
2171 | employee_resource_resource | hr | resource.resource | 1
additionly there is a constraint on this table where the combination of name and module must be unique:
"ir_model_data_module_name_uniq" UNIQUE, btree (name, module)
and resource_resource looks like this (it is not pertinent to this
bug. included for completeness sake.):
id | user_id | name
----+---------+---------------
1 | 1 | Administrator
The error occurs in the _update() method of ir_model_data class.
After the Administrator employee record is deleted ir_model data looks
like this:
id | name | module | model | res_id
------+-------------------------------------------+-----------+-------------------------+--------
2171 | employee_resource_resource | hr | resource.resource | 1
Table resource_resource remains unchanged.
When the openerp server next tries to update the hr module the following happens:
It tries to determine if there is an orphaned record in the ir_model_data table in addons/base/ir/ir_model_data.py ir_model_data._update():
cr.execute('''SELECT imd.id, imd.res_id, md.id
FROM ir_model_data imd LEFT JOIN %s md ON (imd.res_id = md.id)
WHERE imd.module=%%s AND imd.name=%%s''' % model_obj._table,
(module, xml_id))
results = cr.fetchall()
for imd_id2,res_id2,real_id2 in results:
if not real_id2:
self._get_id.clear_cache(cr.dbname, uid, module, xml_id)
self.get_object_reference.clear_cache(cr.dbname, uid, module, xml_id)
cr.execute('delete from ir_model_data where id=%s', (imd_id2,))
res_id = False
This is where things begin to break down. From the code it appears
that the author is attempting to find orphaned records in
ir_model_data by using a LEFT JOIN query and then removing the rows
where the records in the right hand table do not exist. The problem
with this approach is that the field it is filtering on in the right
hand table is part of the join-predicate: (imd.res_id = md.id). Since
the record containing md.id has been deleted this query will return no
results. The code then assumes there are no orphaned records and tries
to recreate all the records for the resource. However, when it tries
to add the employee_resource_resource record to ir_model data it fails
because the ir_model_data_module_name_uniq index is violated:
id | name | module | model | res_id
------+-------------------------------------------+-----------+-------------------------+--------
2171 | employee_resource_resource | hr | resource.resource | 1
<new>| employee_resource_resource | hr | resource.resource | 1
<new> | employee | hr | hr.employee | 1
To manage notifications about this bug go to:
https://bugs.launchpad.net/openobject-addons/+bug/769632/+subscriptions