今天在 GitHub Trending 上看到一个有意思的项目:Odoo,这是一套基于 Web 的开源商业应用套件,为企业提供从 CRM、电商到制造、库存管理的全链路数字化解决方案。
一、项目概述
Odoo 是一个开源的企业资源规划(ERP)平台,采用模块化架构设计,包含超过 30 个核心应用模块。项目由 Odoo S.A. 维护,在 GitHub 上获得超过 28k stars,是开源 ERP 领域的标杆项目。
核心特性:
- 全栈 Web 应用:基于 Python 后端 + PostgreSQL 数据库 + 现代前端技术栈
- 模块化设计:各应用可独立部署,也可无缝集成形成完整 ERP 系统
- 多租户架构:支持 SaaS 部署模式,单一实例服务多个企业客户
- 工作流引擎:内置可视化业务流程设计器
- 报表系统:支持 PDF/Excel 导出,集成 ReportLab 和 OpenPyXL
应用场景:
- 中小企业数字化转型
- 制造业生产管理(MRP)
- 电商平台后端系统
- 服务型企业项目管理
二、技术原理
2.1 架构设计
Odoo 采用经典的三层架构:
┌─────────────────────────────────────┐
│ Presentation Layer │ ← Web Client (OWL Framework)
├─────────────────────────────────────┤
│ Business Logic │ ← Python + ORM (models/)
├─────────────────────────────────────┤
│ Data Access Layer │ ← PostgreSQL + psycopg2
└─────────────────────────────────────┘
核心技术栈:
- 后端:Python 3.10+(支持 3.14),基于 WSGI 的 Web 服务器
- ORM:自研 ORM 框架,支持复杂查询和模型继承
- 前端:OWL(Odoo Web Library)→ 类似 React 的组件化框架
- 数据库:PostgreSQL 12+,利用 JSONB 类型存储灵活字段
- 依赖管理:requirements.txt 中精确锁定各 Python 版本依赖
从 requirements.txt 可以看到版本适配策略:
# 针对不同 Python 版本使用不同依赖版本
lxml==4.8.0 ; python_version <= '3.10'
lxml==4.9.3 ; python_version > '3.10' and python_version < '3.12'
lxml==5.2.1; python_version >= '3.12' # (Noble - removed html clean)
2.2 模型继承机制
Odoo 的 ORM 提供两种继承方式:
1. 经典继承(_inherit)
class SaleOrder(models.Model):
_inherit = 'sale.order'
delivery_date = fields.Date(string="Delivery Date")
2. 原型继承(_inherits)
class Partner(models.Model):
_inherits = {'res.partner': 'partner_id'}
2.3 请求处理流程
从 setup.py 可以看到入口配置:
scripts=['setup/odoo'],
请求生命周期:
- HTTP 请求 → WSGI Server(Gunicorn/Gevent)
- 路由分发 →
odoo.http.Root匹配控制器 - 认证层 → Session、API Key、OAuth2
- 模型层 → ORM 查询 PostgreSQL
- 视图渲染 → QWeb 模板引擎生成 HTML/JSON
2.4 数据库模型设计
Odoo 使用 PostgreSQL 的以下特性:
- MVCC:多版本并发控制,避免锁竞争
- JSONB 字段:
ir_adapter表存储灵活配置 - GIN 索引:加速
product_template的全文搜索 - 分区表:
account_move_line按时间分区提升查询性能
三、安装与快速开始
3.1 环境要求
系统依赖:
- Python 3.10+(推荐 3.12)
- PostgreSQL 12+(推荐 16)
- 系统库:libxml2, libxslt, libsasl2(见
requirements.txt)
Python 依赖安装:
# 创建虚拟环境
python3 -m venv odoo-venv
source odoo-venv/bin/activate
# 安装依赖(自动匹配 Python 版本)
pip install -r requirements.txt
3.2 安装步骤
1. 数据库配置
# 创建 PostgreSQL 用户
sudo -u postgres createuser -s odoo
sudo -u postgres psql -c "ALTER USER odoo WITH PASSWORD 'odoo';"
2. 初始化 Odoo
# 克隆仓库
git clone https://github.com/odoo/odoo.git
cd odoo
git checkout 18.0 # 稳定版本
# 配置文件
cp setup/odoo.conf /etc/odoo.conf
# 编辑 /etc/odoo.conf 设置 db_password, addons_path
# 启动服务
python3 odoo-bin -c /etc/odoo.conf -d mycompany --addons-path=addons
3. 最简运行示例
# 快速启动(使用 SQLite 替代 PostgreSQL 用于开发)
python3 odoo-bin --db-filter=^%d$ --database=test --addons-path=addons,enterprise
访问 http://localhost:8069,使用 admin/admin 登录。
四、使用方法与实战
4.1 基础用法:创建新模块
模块目录结构:
my_module/
├── __manifest__.py # 模块声明
├── __init__.py
├── models/
│ ├── __init__.py
│ └── my_model.py # 业务模型
├── views/
│ └── my_model_views.xml # 视图定义
└── security/
└── ir.model.access.csv # 权限配置
模型定义示例(models/my_model.py):
from odoo import models, fields, api
class MyModel(models.Model):
_name = 'my.model'
_description = 'My Custom Model'
name = fields.Char(string='Name', required=True)
value = fields.Float(string='Value')
state = fields.Selection([
('draft', 'Draft'),
('confirmed', 'Confirmed'),
('done', 'Done')
], string='Status', default='draft')
@api.model_create_multi
def create(self, vals_list):
# 业务逻辑:自动生成序列号
for vals in vals_list:
if not vals.get('name'):
vals['name'] = self.env['ir.sequence'].next_by_code('my.model')
return super().create(vals_list)
4.2 进阶用法:工作流自动化
使用自动化动作(Automation Rules):
<record id="rule_send_email" model="base.automation">
<field name="name">Send Email on Order Confirm</field>
<field name="model_id" ref="sale.model_sale_order"/>
<field name="trigger">on_write</field>
<field name="filter_domain">[('state', '=', 'sale')]</field>
<field name="server_action_id" ref="action_send_confirm_email"/>
</record>
4.3 实际项目示例:电商集成
场景: 将 Shopify 订单同步到 Odoo
步骤:
- 安装
sale、account模块 - 创建
shopify.connector模块 - 使用 Odoo 外部 API 同步订单:
import requests
from odoo import models, fields, api
class ShopifyConnector(models.Model):
_name = 'shopify.connector'
def sync_orders(self):
"""从 Shopify 拉取订单并创建 Odoo 销售订单"""
shopify_orders = requests.get(
f'https://{self.shop_url}/admin/orders.json',
headers={'X-Shopify-Access-Token': self.api_key}
).json()['orders']
for order in shopify_orders:
# 映射 Shopify 订单到 Odoo
so_vals = {
'partner_id': self._get_or_create_customer(order['customer']),
'order_line': [(0, 0, {
'product_id': self._find_product(line['product_id']),
'product_uom_qty': line['quantity'],
'price_unit': line['price'],
}) for line in order['line_items']]
}
self.env['sale.order'].create(so_vals)
五、常见问题与解决方案
5.1 安装失败
问题: pip install -r requirements.txt 失败(lxml 编译错误)
原因: 缺少系统开发库
解决:
# Ubuntu/Debian
sudo apt-get install libxml2-dev libxslt1-dev zlib1g-dev
# macOS
brew install libxml2 libxslt
5.2 运行时错误
问题: psycopg2.OperationalError: FATAL: password authentication failed
原因: PostgreSQL 客户端认证配置错误
解决: 编辑 /etc/postgresql/16/main/pg_hba.conf:
# 将 peer 改为 md5
local all all md5
5.3 性能问题
问题: 列表视图加载缓慢(超过 10 秒)
原因: 缺少数据库索引或 ORM 查询未优化
解决:
- 在模型字段添加索引:
order_id = fields.Many2one(index=True) # 创建 B-tree 索引
- 使用
read_group替代多次search:
# 低效
orders = self.env['sale.order'].search([])
amounts = [o.amount_total for o in orders]
# 高效
amounts = self.env['sale.order'].read_group(
[('state', '=', 'sale')],
['amount_total'],
[]
)
5.4 兼容性问题
问题: Python 3.12+ 依赖冲突
原因: 某些库尚未支持 Python 3.12
解决: 根据 requirements.txt 中的版本约束,使用虚拟环境隔离:
# 使用 Python 3.11 运行 Odoo
pyenv install 3.11.8
pyenv local 3.11.8
六、总结
Odoo 作为开源 ERP 的领导者,其技术架构体现了多个优秀实践:
- 模块化设计:通过
_inherit机制实现松耦合,易于二次开发 - 多版本适配:
requirements.txt中精细的版本约束确保跨 Python 版本兼容 - 企业级特性:内置工作流、报表、多公司支持,适合中大型企业
- 活跃社区:超过 3000+ 第三方模块,覆盖各行业需求
适用场景建议:
- ✅ 适合:需要高度定制化的企业(制造、零售、服务)
- ✅ 适合:预算有限但需专业 ERP 功能的初创公司
- ⚠️ 谨慎:超大规模企业(需评估性能瓶颈)
- ⚠️ 谨慎:无 Python 开发资源的团队
学习路径:
- 官方 eLearning:https://www.odoo.com/slides
- 开发者教程:https://www.odoo.com/documentation/master/developer
- 社区模块:https://apps.odoo.com
项目开源协议为 LGPL-3,企业可免费使用核心功能,如需官方支持可购买企业版。
GitHub 仓库: https://github.com/odoo/odoo
在线演示: https://runbot.odoo.com
社区论坛: https://www.odoo.com/forum/help-1