第4讲、Odoo 18 模块系统源码全解与架构深度剖析【modules】
引言
Odoo 是一款强大的开源企业资源规划(ERP)与客户关系管理(CRM)系统,其核心竞争力之一在于高度模块化的架构设计。模块系统不仅是 Odoo 框架的基石,更是实现功能灵活扩展与定制的关键。本文将结合 Odoo 18 的源码,系统梳理模块系统的核心组件与工作机制,帮助开发者深入理解 Odoo 的模块加载、依赖管理、数据导入、模型注册等关键流程。
模块系统整体架构
Odoo 的模块系统由多个协同工作的组件构成,每个组件负责特定的功能:
- 模块发现与路径管理:查找可用模块并管理模块路径。
- 模块清单(manifest)解析:解析模块的元数据信息。
- 依赖关系管理:构建和管理模块间的依赖关系。
- 模块加载与初始化:按正确顺序加载和初始化模块。
- 数据库初始化与管理:在数据库中注册和管理模块信息。
- 模型注册与管理:注册和初始化模块中定义的模型。
- 版本迁移管理:处理模块升级过程中的数据和结构迁移。
- 数据库中性化:清理或重置数据库中的特定数据。
下文将详细分析这些核心文件的作用与实现。
核心文件详细分析
init.py - 模块系统入口
__init__.py
是 Odoo 模块系统的入口文件,定义了模块管理的基本结构和导入路径。其主要职责包括:
- 导入核心组件:导入同目录下的其他核心模块文件(如 db、graph、loading、migration、module、registry、neutralize)。
- 导出关键函数:如
load_modules
、reset_modules_state
、get_module_path
、get_modules
、get_manifest
等,便于开发者通过odoo.modules
命名空间统一访问核心功能,无需关心具体实现细节。
db.py - 数据库初始化与管理
db.py
负责数据库层面的初始化和管理,确保模块系统在数据库中的基础结构正确建立。主要功能包括:
- 数据库初始化检查:
is_initialized
检查ir_module_module
表是否存在,以判断数据库是否已为 ORM 系统初始化。 - 数据库初始化:
initialize
执行基础 SQL 文件,创建模块分类,并在数据库中注册所有可用模块的信息。 - 模块分类创建:
create_categories
支持多级分类自动创建,保证模块分类的层级结构。 - 数据库功能检查:
has_unaccent
和has_trigram
检查数据库是否支持全文检索优化,直接影响 Odoo 搜索性能。
graph.py - 模块依赖关系管理
graph.py
实现了模块依赖关系图的构建和管理,解决了模块加载顺序的关键问题。主要组件包括:
- Graph 类:继承自字典,用于表示模块依赖关系图,支持节点添加、状态更新、依赖遍历等。
- Node 类:表示依赖图中的一个模块节点,包含模块名称、依赖信息、子节点列表等属性,支持递归遍历。
- 依赖顺序遍历:
Graph
的__iter__
方法实现了按依赖深度的遍历,确保依赖模块先于被依赖模块处理。
依赖图的构建确保了模块按照拓扑排序的顺序加载,是模块安装、升级、卸载的基础。
loading.py - 模块加载与初始化
loading.py
是模块加载和初始化的执行引擎,负责将模块从静态代码转变为运行中的系统组件。主要功能包括:
- 数据加载:
load_data
支持多种数据类型(XML、CSV、SQL),并自动处理noupdate
标记。 - 演示数据加载:
load_demo
专门用于加载演示数据,加载失败时不中断模块安装。 - 模块加载:
load_module_graph
按依赖顺序批量加载模块,执行从代码加载到数据导入的完整过程。 - 模块标记加载:
load_marked_modules
支持按状态批量加载模块。 - 模块加载入口:
load_modules
是注册表初始化的关键入口,自动处理 base 模块优先、依赖递归、语言加载、模块状态切换、缓存刷新等。
migration.py - 版本迁移管理
migration.py
管理模块版本迁移,确保模块在升级过程中能够平滑过渡,数据和结构能够正确迁移。主要组件包括:
- MigrationManager 类:负责在模块升级过程中执行迁移脚本,支持 pre/post/end 三阶段钩子。
- 迁移脚本组织:支持
migrations
目录下按版本号组织迁移脚本,0.0.0
目录下的脚本可在所有版本变更时执行。 - 脚本签名校验:强制要求迁移脚本为
migrate(cr, installed_version)
,防止格式错误导致升级中断。
module.py - 模块发现与管理
module.py
提供了模块发现、加载和管理的基础功能,是 Odoo 模块系统的基石。主要功能包括:
- 系统路径初始化:
initialize_sys_path
设置 Odoo 的模块路径系统,确保模块可被正确导入。 - 模块路径查找:
get_module_path
查找指定模块的文件系统路径。 - 资源路径管理:
get_resource_path
及相关函数用于获取模块中特定资源的路径。 - 模块清单解析:
load_manifest
和get_manifest
解析模块的 manifest 文件,获取元数据信息。 - 模块加载:
load_openerp_module
动态加载模块 Python 代码,并执行 post_load 钩子。 - 模块发现:
get_modules
和get_modules_with_version
支持批量发现所有可用模块及其版本。
neutralize.py - 数据库中性化处理
neutralize.py
实现了数据库中性化处理,用于清理或重置数据库中的特定数据,使其恢复到中性状态。主要功能包括:
- 获取已安装模块:
get_installed_modules
获取数据库中所有已安装、待升级或待移除的模块列表。 - 获取中性化查询:
get_neutralization_queries
获取模块中定义的中性化 SQL 查询。 - 执行中性化:
neutralize_database
批量执行所有已安装模块的中性化脚本,适合演示/测试环境快速重置。
registry.py - 模型注册与管理
registry.py
是 Odoo 模型注册表的核心实现,负责模型的注册、加载和缓存,是 Odoo ORM 系统的基础。主要组件包括:
- Registry 类:模型注册表的核心类,单例模式,每个数据库独立注册表。
- 模型设置:
setup_models
完成模型的三阶段初始化,确保所有组件(字段、方法、继承关系等)都被正确初始化。 - 模块加载:
load
方法加载指定模块的模型,并返回被修改的模型名称列表。 - 缓存机制:内置多级缓存,并支持多进程信号同步,极大提升性能和一致性。
- 事务管理:支持只读和读写游标、测试模式、缓存失效、信号通知等高级特性。
模块系统工作流程
Odoo 模块系统的工作流程大致分为以下阶段:
- 初始化阶段:设置模块路径,检查数据库状态,必要时初始化数据库结构。
- 模块发现阶段:发现所有可用模块,解析 manifest 获取元数据。
- 依赖解析阶段:构建模块依赖关系图,确定加载顺序。
- 模块加载阶段:按依赖顺序加载模块,导入数据,注册模型。
- 模型注册阶段:注册和初始化模型,完成模型设置。
- 迁移执行阶段:执行模块的迁移脚本,确保数据和结构正确迁移。
- 缓存管理阶段:通过注册表的缓存机制管理各种缓存,提升系统性能。
源码细节补充与进阶解读
1. 各核心文件的源码亮点补充
(此处内容已较为完善,略作语言优化,详见上文)
2. 源码调用链与流程图
Odoo 模块系统的加载流程大致如下:
load_modules
作为注册表初始化的入口,负责整体流程调度。load_module_graph
按依赖顺序批量加载模块,处理迁移、数据导入、模型注册等。load_openerp_module
动态加载模块 Python 代码,并执行 post_load 钩子。Registry.load
和Registry.setup_models
负责模型的注册与初始化。MigrationManager.migrate_module
负责模块升级过程中的数据迁移。load_data
/load_demo
负责数据文件的导入。
3. 典型场景举例
新模块安装
get_modules
发现新模块。Graph
构建依赖关系,确保依赖模块先加载。load_module_graph
依次加载模块,导入数据,注册模型。Registry.setup_models
完成模型初始化,模块可用。
模块升级
- 检测到 manifest 版本变更。
MigrationManager
自动执行对应版本的迁移脚本。- 数据结构和数据内容平滑升级,保证兼容性。
数据库中性化
neutralize_database
批量执行所有已安装模块的neutralize.sql
。- 快速清理业务数据,适合演示/测试环境重置。
4. 实践建议
- 自定义模块开发:建议严格编写 manifest、依赖、迁移脚本和中性化脚本,确保模块的可维护性和可升级性。
- 调试与排错:遇到模块加载、依赖、迁移等问题时,可结合日志和源码,定位到具体的加载流程和依赖节点。
- 利用缓存与信号机制:合理利用 Odoo 的多级缓存和信号同步机制,提升系统性能和一致性。
通过结合源码细节和实际场景,开发者可以更深入理解 Odoo 的模块系统原理,开发出高质量、易维护、可扩展的 Odoo 应用。
总结
Odoo 的模块系统是一个复杂而精心设计的组件,通过模块化的方式组织代码和功能,提供了高度的灵活性和可扩展性。
深入理解模块系统的各个组件及其工作原理,有助于开发者更高效地利用 Odoo 的模块机制,开发高质量的企业级应用。
模块系统的核心文件各司其职,共同构成了 Odoo 的模块加载和管理框架:
__init__.py
作为入口点,提供对外 API 接口db.py
负责数据库层面的初始化和管理graph.py
处理模块依赖关系loading.py
执行模块的加载和初始化migration.py
管理版本迁移module.py
提供模块发现和管理的基础功能neutralize.py
实现数据库中性化处理registry.py
负责模型的注册和管理
这些组件共同构成了 Odoo 的模块系统,使其能够以灵活、可扩展的方式组织和加载功能模块,是 Odoo 框架的核心基础设施。
相关文章:

第4讲、Odoo 18 模块系统源码全解与架构深度剖析【modules】
引言 Odoo 是一款强大的开源企业资源规划(ERP)与客户关系管理(CRM)系统,其核心竞争力之一在于高度模块化的架构设计。模块系统不仅是 Odoo 框架的基石,更是实现功能灵活扩展与定制的关键。本文将结合 Odoo…...

pytorch简单线性回归模型
模型五步走 1、获取数据 1. 数据预处理 2.归一化 3.转换为张量 2、定义模型 3、定义损失函数和优化器 4、模型训练 5、模型评估和调优 调优方法 6、可视化(可选) 示例代码 import torch import torch.nn as nn import numpy as np import matplot…...
在 HTML 文件中添加图片的常用方法
本文详解HTML图片插入方法:1)通过<img>标签实现,必须含src和alt属性;2)路径支持绝对/相对引用;3)建议设置width/height保持比例;4)响应式方案用srcset适配不同设备…...

四、web安全-行业术语
1. 肉鸡 所谓“肉鸡”是一种很形象的比喻,比喻那些可以随意被我们控制的电脑,对方可以是WINDOWS系统,也可以是UNIX/LINUX系统,可以是普通的个人电脑,也可以是大型的服务器,我们可以象操作自己的电脑那样来…...
Kafka核心技术解析与最佳实践指南
Apache Kafka作为分布式流处理平台的核心组件,以其高吞吐、低延迟和可扩展性成为现代数据架构的基石。本文基于Kafka官方文档,深度解析其核心技术原理,并结合实践经验总结关键技巧与最佳实践。 Kafka的高性能源于其精巧的架构设计࿰…...

Unity基础学习(十二)Unity 物理系统之范围检测
目录 一、关于范围检测的主要API: 1. 盒状范围检测 Physics.OverlapBox 2. 球形范围检测 Physics.OverlapSphere 3. 胶囊范围检测 Physics.OverlapCapsule 4. 盒状检测 NonAlloc 版 5. 球形检测 NonAlloc 版 6. 胶囊检测 NonAlloc 版 二、关于API中的两个重…...

JVM 的垃圾回收机制 GC
C/C 这样的编程语言中,申请内存的时候,是需要用完了,进行手动释放的 C 申请内存 1)局部变量(不需要手动释放) 2)全局变量(不需要手动释放) 3)动态申请 malloc(通过 free 进行释放的) C 申请内存 1)局部变量 2)全局变量/静态变量 3)动态申请 new 通过 delete 进行释放 …...
TypeScript 针对 iOS 不支持 JIT 的优化策略总结
# **TypeScript 针对 iOS 不支持 JIT 的优化策略总结** 由于 iOS 的 **JavaScriptCore (JSC)** 引擎 **禁用 JIT(Just-In-Time 编译)**,JavaScript 在 iOS 上的执行性能较差,尤其是涉及动态代码时。 **TypeScript(T…...
00 QEMU源码中文注释与架构讲解
QEMU源码中文注释与架构讲解 先占坑:等后续完善后再更新此文章 注释作者将狼才鲸创建日期2025-05-30更新日期NULL CSDN阅读地址:00 QEMU源码中文注释与架构讲解Gitee源码仓库地址:才鲸嵌入式/qemu 一、前言 参考网址 QEMU 源码目录简介qe…...
ansible template 文件中如果包含{{}} 等非ansible 变量处理
在 Ansible 模板中,如果你的 Python 脚本里有大量 {}、f""、或者其他 Jinja 会误解析的语法,就需要用 {% raw %}…{% endraw %} 把它们包起来,只在需要替换变量的那一行单独“放行”。例如: {% raw %} #!/usr/bin/env …...
Screen 连接远程服务器(Ubuntu)
连接 1. 安装screen 默认预安装,可以通过命令查看: screen --version 若未安装: # Ubuntu/Debian sudo apt-get install screen 2. 本机连接远程服务器 ssh root192.168.x.x 在远程服务器中打开screen: screen -S <nam…...

路由器、网关和光猫三种设备有啥区别?
无论是家中Wi-Fi信号的覆盖,还是企业网络的高效运行,路由器、网关和光猫这些设备都扮演着不可或缺的角色。然而,对于大多数人来说,这三者的功能和区别却像一团迷雾,似懂非懂。你是否曾疑惑,为什么家里需要光…...

vscode实时预览编辑markdown
vscode实时预览编辑markdown 点击vsode界面,实现快捷键如下: 按下快捷键 CtrlShiftV(Windows/Linux)或 CommandShiftV(Mac)即可在侧边栏打开 Markdown 预览。 效果如下:...

2505软考高项第一、二批真题终极汇总
第一批2025.05综合题(75道选择题) 1、2025 年中央一号文件对进一步深化农村改革的各项任务作出全面部署。“推进农业科技力量协同攻关”的相关措施不包括()。 A.强化农业科研资源力量统筹,培育农业科技领军企业 B.发挥农业科研平台作用&…...

云原生安全基础:Linux 文件权限管理详解
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 在云原生环境中,Linux 文件权限管理是保障系统安全的核心技能之一。无论是容器化应用、微服务架构还是基础设施即代码(IaC…...
A类地址中最小网络号(0.x.x.x) 默认路由 / 无效/未指定地址
A类地址中最小网络号(0.x.x.x)为何不指派? 在IPv4的A类地址中,网络号范围为 0.0.0.0 ~ 127.0.0.0,但网络号0(即0.x.x.x) 通常不被指派给任何网络,原因如下: 1. 0.x.x.x …...

[嵌入式实验]实验二:LED控制
一、实验目的 1.熟悉开发环境 2.控制LED灯 二、实验环境 硬件:STM32开发板、CMSIS-DAP调试工具 软件:ARM的IDE:Keil C51 三、实验内容 1.实验原理 (1)LED灯原理与点亮 LED即发光二极管,有电流通过…...

6.4.2_3最短路径问题_Floyd算法
Floyd弗洛伊德 膜拜大佬,给大佬鞠躬鞠躬鞠躬。。。。。。。。。 Floyd算法 ----解决顶点间的最短路径: 过程: 如下: 初始化(没有中转点):2个邻接矩阵A和path,第一个是没有中转点的2个顶点之间的最短路径…...

<PLC><socket><西门子>基于西门子S7-1200PLC,实现手机与PLC通讯(通过websocket转接)
前言 本系列是关于PLC相关的博文,包括PLC编程、PLC与上位机通讯、PLC与下位驱动、仪器仪表等通讯、PLC指令解析等相关内容。 PLC品牌包括但不限于西门子、三菱等国外品牌,汇川、信捷等国内品牌。 除了PLC为主要内容外,PLC相关元器件如触摸屏(HMI)、交换机等工控产品,如…...
day 33 python打卡
作业:今日的代码,要做到能够手敲。这已经是最简单最基础的版本了。 import torch print(torch.__version__) print(torch.version.cuda) print(torch.cuda.is_available()) import torch# 检查CUDA是否可用 if torch.cuda.is_available():print("CU…...
开发时如何通过Service暴露应用?ClusterIP、NodePort和LoadBalancer类型的使用场景分别是什么?
一、Service核心概念 Service通过标签选择器(Label Selector)关联Pod,为动态变化的Pod集合提供稳定的虚拟IP和DNS名称,主要解决: 服务发现负载均衡流量路由 二、Service类型详解 1. ClusterIP(默认类型…...
【机械视觉】Halcon—【六、交集并集差集和仿射变换】
【机械视觉】Halcon—【六、交集并集差集和仿射变换】 目录 【机械视觉】Halcon—【六、交集并集差集和仿射变换】 介绍 交集并集差集介绍: 1. 交集(Intersection) 2. 并集(Union) 3. 差集(Differenceÿ…...

深度学习核心网络架构详解(续):从 Transformers 到生成模型
在上一篇文章中,我们详细介绍了卷积神经网络 (CNN)、循环神经网络 (RNN) 及其变体 LSTM 和 GRU。本文将继续探讨其他必须掌握的深度学习网络架构,包括 Transformers、生成对抗网络 (GAN)、自编码器 (Autoencoder) 以及强化学习基础。我们将深入讲解这些技…...

AI智能混剪视频大模型开发方案:从文字到视频的自动化生成·优雅草卓伊凡
AI智能混剪视频大模型开发方案:从文字到视频的自动化生成优雅草卓伊凡 引言:AI视频创作的未来已来 近年来,随着多模态大模型(如Stable Diffusion、Sora、GPT-4)的爆发式发展,AI已经能够实现从文字生成图像…...

allWebPlugin中间件VLC专用版之截图功能介绍
背景 VLC控件原有接口具有视频截图方法,即video对象的takeSnapshot方法,但是该方法返回的是一个IPicture对象,不适合在谷歌等现代浏览器上使用。因此,本人增加一个新的视频截图方法takeSnapshot2B64方法,直接将视频截图…...
【JavaSE】异常处理学习笔记
异常处理 -异常介绍 基本概念 Java语言中,将程序执行中发生的不正常情况称为“异常”。(开发过程中的语法错误和逻辑错误不是异常) 执行过程中所发生的异常事件可分为两类 Error(错误):Java虚拟机无法解决…...

Scratch节日 | 六一儿童节
六一儿童节到啦!快来体验这款超简单又超好玩的 六一儿童节 小游戏吧!只需要一只鼠标,就能尽情释放你的创意,绘出属于你自己的缤纷世界! 🎮 玩法介绍 鼠标滑动:在屏幕上随意滑动鼠标,…...

深度解析:跨学科论文 +“概念迁移表” 模板写作全流程
跨学科论文速通!融合“概念迁移表”的写作导航模板 你的论文是否曾被导师皱眉评价为“四不像”?不同学科的术语在稿纸上打架,核心逻辑若隐若现? 别让心血沦为学术混搭的牺牲品。一张精心设计的 概念迁移表,能将两个看…...

深度剖析Node.js的原理及事件方式
早些年就接触过Node.js,当时对于这个连接前后端框架就感到很特别。尤其是以独特的异步阻塞特性,重塑了了服务器端编程的范式。后来陆陆续续做了不少项目,通过实践对它或多或少增强了不少理解。今天,我试着将从将从原理层剖析其运行…...

VScode-使用技巧-持续更新
一、Visual Studio Code - MACOS版本 复制当前行 shiftoption方向键⬇️ 同时复制多行 shiftoption 批量替换换行 在查找和替换面板中,你会看到一个 .∗ 图标(表示启用正则表达式)。确保这个选项被选中,因为我们需要使用正则…...