Odoo加載機制指導流程

Odoo的啓動通過openerp-server腳本完成,它是系統的入口。

然後加載配置文件openerp-server.conf 或者 openerp_serverrc;

openerp-server.conf的主要內容:

這個文件缺省是沒有的,Odoo系統會有一個默認值,但是一般情況我們都需配置這個文件。

啓動http服務器,監聽端口。

模塊加載:

模塊加載外層就是封裝一個Registry(Mapping)對象:實際是一個字典,它包含對應的db,model等映射關係,一個DB對應一個Registry。後續的操作都會圍繞這個Registry進行,將相關的數據賦值給相應的屬性項。

1. 初始化數據庫(初次運行)
1)加載base模塊下的base.sql文件並執行。
此時數據庫表爲:

複製代碼

CREATE TABLE ir_actions (
  id serial,
  primary key(id)
);
CREATE TABLE ir_act_window (primary key(id)) INHERITS (ir_actions);
CREATE TABLE ir_act_report_xml (primary key(id)) INHERITS (ir_actions);
CREATE TABLE ir_act_url (primary key(id)) INHERITS (ir_actions);
CREATE TABLE ir_act_server (primary key(id)) INHERITS (ir_actions);
CREATE TABLE ir_act_client (primary key(id)) INHERITS (ir_actions);


CREATE TABLE ir_model (
  id serial,
  model varchar NOT NULL,
  name varchar,
  state varchar,
  info text,
  primary key(id)
);

CREATE TABLE ir_model_fields (
  id serial,
  model varchar NOT NULL,
  model_id integer references ir_model on delete cascade,
  name varchar NOT NULL,
  relation varchar,
  select_level varchar,
  field_description varchar,
  ttype varchar,
  state varchar default 'base',
  relation_field varchar,
  translate boolean default False,
  serialization_field_id integer references ir_model_fields on delete cascade, 
  primary key(id)
);

CREATE TABLE res_lang (
    id serial,
    name VARCHAR(64) NOT NULL UNIQUE,
    code VARCHAR(16) NOT NULL UNIQUE,
    primary key(id)
);

CREATE TABLE res_users (
    id serial NOT NULL,
    active boolean default True,
    login varchar(64) NOT NULL UNIQUE,
    password varchar(64) default null,
    -- No FK references below, will be added later by ORM
    -- (when the destination rows exist)
    company_id integer, -- references res_company,
    partner_id integer, -- references res_partner,
    primary key(id)
);

create table wkf (
    id serial,
    name varchar(64),
    osv varchar(64),
    on_create bool default false,
    primary key(id)
);

CREATE TABLE ir_module_category (
    id serial NOT NULL,
    create_uid integer, -- references res_users on delete set null,
    create_date timestamp without time zone,
    write_date timestamp without time zone,
    write_uid integer, -- references res_users on delete set null,
    parent_id integer REFERENCES ir_module_category ON DELETE SET NULL,
    name character varying(128) NOT NULL,
    primary key(id)
);

CREATE TABLE ir_module_module (
    id serial NOT NULL,
    create_uid integer, -- references res_users on delete set null,
    create_date timestamp without time zone,
    write_date timestamp without time zone,
    write_uid integer, -- references res_users on delete set null,
    website character varying(256),
    summary character varying(256),
    name character varying(128) NOT NULL,
    author character varying(128),
    icon varchar,
    state character varying(16),
    latest_version character varying(64),
    shortdesc character varying(256),
    category_id integer REFERENCES ir_module_category ON DELETE SET NULL,
    description text,
    application boolean default False,
    demo boolean default False,
    web boolean DEFAULT FALSE,
    license character varying(32),
    sequence integer DEFAULT 100,
    auto_install boolean default False,
    primary key(id)
);
ALTER TABLE ir_module_module add constraint name_uniq unique (name);

CREATE TABLE ir_module_module_dependency (
    id serial NOT NULL,
    create_uid integer, -- references res_users on delete set null,
    create_date timestamp without time zone,
    write_date timestamp without time zone,
    write_uid integer, -- references res_users on delete set null,
    name character varying(128),
    module_id integer REFERENCES ir_module_module ON DELETE cascade,
    primary key(id)
);

CREATE TABLE ir_model_data (
    id serial NOT NULL,
    create_uid integer,
    create_date timestamp without time zone,
    write_date timestamp without time zone,
    write_uid integer,
    noupdate boolean,
    name varchar NOT NULL,
    date_init timestamp without time zone,
    date_update timestamp without time zone,
    module varchar NOT NULL,
    model varchar NOT NULL,
    res_id integer,
    primary key(id)
);

-- Records foreign keys and constraints installed by a module (so they can be
-- removed when the module is uninstalled):
--   - for a foreign key: type is 'f',
--   - for a constraint: type is 'u' (this is the convention PostgreSQL uses).
CREATE TABLE ir_model_constraint (
    id serial NOT NULL,
    date_init timestamp without time zone,
    date_update timestamp without time zone,
    module integer NOT NULL references ir_module_module on delete restrict,
    model integer NOT NULL references ir_model on delete restrict,
    type character varying(1) NOT NULL,
    name varchar NOT NULL,
    primary key(id)
);

-- Records relation tables (i.e. implementing many2many) installed by a module
-- (so they can be removed when the module is uninstalled).
CREATE TABLE ir_model_relation (
    id serial NOT NULL,
    date_init timestamp without time zone,
    date_update timestamp without time zone,
    module integer NOT NULL references ir_module_module on delete restrict,
    model integer NOT NULL references ir_model on delete restrict,
    name varchar NOT NULL,
    primary key(id)
);  

CREATE TABLE res_currency (
    id serial,
    name varchar NOT NULL,
    primary key(id)
);

CREATE TABLE res_company (
    id serial,
    name varchar NOT NULL,
    partner_id integer,
    currency_id integer,
    primary key(id)
);

CREATE TABLE res_partner (
    id serial,
    name varchar,
    company_id integer,
    primary key(id)
);

複製代碼

 


這20張表是odoo系統級的,它是模塊加載及系統運行的基礎。後續模塊生成的表及相關數據都可以在這20張中找到蛛絲馬跡。


2)數據庫表初始化後,就可以加載模塊數據(addons)到數據庫了,這個也是odoo作爲平臺靈活的原因,所有的數據都在數據庫。
找到addons-path下所有的模塊,然後一個一個的加載到數據庫中。
Info就是load模塊的__openerp__.py文件,它是一個dict。

根據__openerp__.py中定義的category創建分類信息:
將模塊信息寫入ir_module_module表:
將module信息寫入ir_model_data表:
一個module要寫兩次ir_model_data表,
寫module的dependency表:

根據依賴關係進行判斷,遞歸更新那些需要auto_install的模塊狀態爲“to install”。


到目前爲止,模塊的加載都是在數據庫級別,只是將“模塊文件”信息存入數據庫表,但是還沒有真正加載到程序中。
Odoo運行時查找object是通過Registry.get()獲取的,而不是通過python自己的機制來找到相應的object,所以odoo在加載模塊時會把模塊下包含的model全部註冊到models.py的module_to_models字典中。

下面的步驟就是加載模塊到內存:
3)加載base模塊

創建一個包含model層級的節點圖,第二行代碼將從數據庫更新數據到graph中。然後調用load_module_graph方法加載模塊,最終執行加載的方法:
這個方法是odoo加載model的核心,通過 __import__方法加載模塊,這個是python的機制,當import到某個繼承了BaseModel類的class時,它的實例化將有別於python自身的實例化操作,
後者說它根本不會通過python自身的__new__方法創建實例,所有的實例創建都是通過 _build_model 方法及元類創建,並註冊到module_to_models中。通過這種方式實例化model就可以解決我們在xml中配置model時指定的繼承,字段,約束等各種屬性。

4)標記需要加載或者更新的模塊(db)
5)加載被標記的模塊(加載過程與加載base模塊一致)
6)完成及清理安裝
7)清理菜單
8)刪除卸載的模塊
9)覈實model的view
10)運行post-install測試

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章