Odoo丨Odoo框架源码研读二:ORM框架与日志

Odoo丨Odoo框架源码研读二:ORM框架与日志

而Odoo在实际开发的大多数场景都是基于它的ORM框架进行的,所以本期我们将带来Odoo框架源码的第二期内容——ORM和日志。

*ORM*

Odoo是通过Controller控制器,来控制前后台的交互。上一期我们详细的介绍了如何让请求顺利到达Controller控制器。

那么当请求到达Controller后,又如何来实现后端的业务逻辑呢?这就不得不提到Odoo一个非常强大的类——Environment。

Environment:

通过_loca属性,Environment可以直接管理线程中的environments上下文状态,并且包装了ORM相关四个属性:

  • cr:当前数据库游标对象,通过self.env.cr(sql),可以直接执行SQL语句进行数据的CRUD;
  • uid:当前登陆用户ID,通过self.env.uid获取当前登陆用户ID;
  • context:当前上下文字典,通过self.env.context,我们可以缓存前后端的数据用来交互;
  • su:切换超级用户模式,通过它我们可以越过model_access 权限的校验,直接操作数据。

而且Environment还提供了Model name和Model之间的映射,通过self.env[ModelName] 就可以直接调用Model的API ,非常强大。

Odoo丨Odoo框架源码研读二:ORM框架与日志_第1张图片

现在,再回头看Controller中的方法,可以看到,通过request.env[model]可以直接获取对应的Model对象,然后直接调用Model的方法。

Model

Odoo中一切都是基于Model编程。即使是前端的menu、action、view,都是也都有对应 Model,和业务数据无异。

创建一个Model ,然后通过简单的视图配置,那么这个Model对应的CRUD基础功能就已经实现,这些都归功于Odoo对于Model的抽象。

Odoo中的model分为三类:AbstractModel、Model、TransientModel;

  • Model:⽤于常规的数据库持久化模型;
  • TransientModel:⽤于存储在数据库中的临时数据,但会经常⾃动清理;
  • AbstractModel:⽤于要由多个继承模型共享的抽象超类。

继承关系如下图 ⬇

Odoo丨Odoo框架源码研读二:ORM框架与日志_第2张图片

Odoo丨Odoo框架源码研读二:ORM框架与日志_第3张图片

从源码中可以看出AbstractModel 是Model 和TransientModel的父类。而这个三者的区别也主要在_auto、_register、_abstract、_transient这四个属性上。

由此可以AbstractModel是抽象类,不会在数据库创建表,Model和TransientModel 不是抽象类,会在数据库建表,但TransientModel建的是临时表,数据会被系统定期清除,这个可以在系统中设置清除频率。

由于这种特性的不同,三个Model的用途也不相同。

TransientModel由于存临时表的特性,多用来做wizard向导视图,存储临时缓存数据;

Model多用于做业务的主要Model,AbstractModel多用来抽象做父类,由于不创建表的特性,有时也会用来做向导视图。

新模块中的Model,根据功能需要去继承这三个类,由于这三个父类中丰富的API方法,新建 Model在创建完字段后,功能就已经基本完善,如果有定制化的逻辑,只需要重写父类的方法就可以了。

Field

Model中的Field不是Python的基础类型,而是继承Odoo封装的Field类。

Odoo丨Odoo框架源码研读二:ORM框架与日志_第4张图片

因此,在Model字段赋值的时候,和基础类型字段不同,会调用Field中的API方法,这是容易踩坑的地方。

*日志*

Odoo的日志是在Python的logging基础模块之上,做了定制化的封装和配置。这部份代码主要在odoo/netsvc.py文件中。

Odoo定义了自己的Filter对象、Formatter对象、以及Handler对象。

图片

Odoo丨Odoo框架源码研读二:ORM框架与日志_第5张图片

  • Handler对象:日志处理器,对传入的日志进行处理。比如PostgreSQLHandler就是把日志存入数据库;
  • Formatter对象: 日志格式器,对日志内容进行格式化;
  • Filter对象:日志过滤器,可以实现复杂的过滤,截取需要的日志内容。

配置参数

1)项目启动的时候,配置管理器configmanager初始化,这个时候会去初始化默认的系统配置,包括日志模块。

2)随后,配置管理器会去加载配置文件odoo.conf中的自定义配置覆盖原先的默认配置。

3)最后,处理完配置加载,Odoo会调用日志初始化代码,根据最终的日志配置去设定相关的logger对象。

Odoo丨Odoo框架源码研读二:ORM框架与日志_第6张图片

上图即为Odoo日志的默认配置。

Odoo丨Odoo框架源码研读二:ORM框架与日志_第7张图片

初始化

初始化过程:

Odoo丨Odoo框架源码研读二:ORM框架与日志_第8张图片

Odoo丨Odoo框架源码研读二:ORM框架与日志_第9张图片

  • 1)设定日志初始化标志 _logger_init ,保证Odoo只会初始化一次logger对象;
  • 2)设定 logRecordFactory ,在日志信息中添加定制化参数信息,这里是将 perf_info 设置成了"";
  • 3)warnings.filterwarnings() 设置警告过滤器,去除一些不必要的告警信息;
  • 4)resetlocale 设置国际化;
  • 5)根据 syslog 配置参数,以及操作系统类别,设置系统日志的handler;
  • 6)给 handler 设置 fomatter;
  • 7)将设定好的 handler 添加到 root logger(root logger 与各个包层级下衍生 logger 的关系这里不做赘述);
  • 8)给 wekzeug 包下的 logger 对象添加 filter;
  • 9)根据 log_db 配置参数设定 postgresqHandler ,确定是否将日志入库,以及 log_db_level 确定入库日志的级别;
  • 10)logging_configurations 设定特定几个包名下logger的配置。

logger的调用

通过logging.logging.getLogger(name)调用前包层级的logger 对象,logging.logging.getLogger() 则返回root logger对象。

本期关于Odoo的ORM和日志就聊到这里,下一期我们会继续聊一下Odoo的异常和流程引擎,感兴趣的小伙伴记得关注我~

你可能感兴趣的:(odoo,python,python,ERP,开源软件)