← Back to team overview

c2c-oerpscenario team mailing list archive

[Bug 769632] Re: Removing Administrator employee record causes future updates of hr module to fail

 

** Branch linked: lp:~openerp-dev/openobject-addons/trunk-bug-769632-ara

-- 
You received this bug notification because you are a member of C2C
OERPScenario, which is subscribed to the OpenERP Project Group.
https://bugs.launchpad.net/bugs/769632

Title:
  Removing Administrator employee record causes future updates of hr
  module to fail

Status in OpenERP Modules (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


References