Reputation: 3555
I have a module built in OpenERP that adds some fields to existing models.
The definition is roughly as follows:
class res_partner(osv.osv):
_name = _inherit = 'res.partner'
_columns = {
'my_special_id': fields.integer('Special ID', required=False, readonly=True),
}
_defaults = {
'my_special_id': lambda *a: None
}
_sql_constraints = [
('special_id_uniq', 'UNIQUE (my_special_id)', 'Must be unique.'),
}
_sql = """CREATE UNIQUE INDEX special_id_limited_uniq
ON res_partner (my_special_id)
WHERE my_special_id != 0
"""
res_partner()
My goal is to have a field (special_id_uniq) that:
My first instinct was to create the _sql_constraint definition above, but this caused issues: apparently OpenERP doesn't have nullable integer fields, so 'None' is treated as 0. This breaks the SQL constraint, as now multiple values of 0 must be allowed.
To get around this, I removed the _sql_constraints option on the model and added the _sql code which creates a PostgreSQL partial index. To verify that it works, I ran the SQL myself on PostgreSQL and it acheives my desired effect. However, when I create a new DB via OpenERP and install my custom module, this SQL is not run. That is because the model is not being created:
def _auto_init(self, cr, context=None):
#...
create = not self._table_exist(cr)
#...
#Line 3046 of openerp/osv/orm.py version 6.1 function _auto_init
if create:
self._execute_sql(cr)
#...
So, how can I run some custom SQL at the point of module installation?
Upvotes: 4
Views: 2304
Reputation: 13342
You can achieve this by adding a function
entry in a data xml file of the module.
<openerp>
<data>
<!-- ... your init data records ...-->
<function model="res.partner" name="_my_init_mehod"/>
</data>
</openerp>
You can see a working example of this in the standard module document
:
document_data.xml
declares a call to the function _attach_parent_id
to migrate all attachments to the new DMS structure at the end of the installation.
Upvotes: 3
Reputation: 3555
Actually, I might have just answered my own question: override _auto_init.
Edit:
Yes, the following works to run the SQL during install / upgrade:
def _auto_init(self, cr, context=None):
ret = super(res_partner, self)._auto_init(cr, context)
self._execute_sql(cr)
return ret
Upvotes: 4