2012-05-29 35 views
4

我有一個內置OpenERP的模塊,它爲現有模型添加了一些字段。在OpenERP中,如何在安裝模塊時強制SQL運行?

的定義大致如下:

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)認爲:

  1. 默認爲null
  2. 是一個整數
  3. 是獨一無二的,除了NULL以外的所有數值

我的第一個直覺就是創建了上面的_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?

回答

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結構在安裝結束遷移。

+0

謝謝,這絕對看起來像是更'OpenERP-esq'的做事方式。 –

+0

如果我們使用多個<函數標籤和多個函數,它們是否會按照xml文件中指定的順序執行?我的預感告訴我是的。這對於模塊版本之間的堆棧升級會很方便,不是嗎?函數的內部當然還需要有條件的來防止多次執行,但順序會很方便。 – Rbjz

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 
+0

我用它來添加一個'CREATE INDEX'語句,它在模塊init和模塊更新上都執行。 (我們將CREATE INDEX包裝在一些條件很好的條件SQL中,這樣它就不會嘗試在已經存在的情況下重新創建索引) –