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測試