我有一个内置在OpenERP中的模块,可以为现有模型添加一些字段。
定义大致如下:
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()
我的目标是拥有一个字段(special_id_uniq):
我的第一直觉是创建上面的_sql_constraint定义,但是这导致了问题:显然OpenERP没有可空的整数字段,因此'None'被视为0.这打破了SQL约束,因为现在多个值为0必须被允许。
为了解决这个问题,我删除了模型上的_sql_constraints选项,并添加了创建PostgreSQL部分索引的_sql代码。为了验证它是否有效,我在PostgreSQL上自己运行了SQL,它实现了我想要的效果。但是,当我通过OpenERP创建一个新数据库并安装我的自定义模块时,不会运行此SQL。那是因为没有创建模型:
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)
#...
那么,如何在模块安装时运行一些自定义SQL?
答案 0 :(得分:4)
实际上,我可能刚刚回答了我自己的问题:覆盖_auto_init。
编辑:
是的,以下工作在安装/升级期间运行SQL:
def _auto_init(self, cr, context=None):
ret = super(res_partner, self)._auto_init(cr, context)
self._execute_sql(cr)
return ret
答案 1 :(得分:3)
您可以通过在模块的数据xml文件中添加function
条目来实现此目的。
<openerp>
<data>
<!-- ... your init data records ...-->
<function model="res.partner" name="_my_init_mehod"/>
</data>
</openerp>
您可以在标准模块document
中看到相关的工作示例:
document_data.xml
声明调用函数_attach_parent_id
,以便在安装结束时将所有附件迁移到新的DMS结构。