资讯详情 Odoo 17数据字典中文翻译与导出实战:字段模型全解析
📅 2026/10/29 18:18:46
简介Odoo 17 中文数据字典是一份由数据库设计工具导出并翻译整理的参考文档面向 Odoo 开发人员、实施顾问和初学者重点解决阅读源码时对底层表结构不熟悉、难以快速定位字段来源的问题。字典以 PostgreSQL 数据库为对象按数据库、schema、数据表的层级组织逐表列出字段、类型、约束及注释从预览可见覆盖 account 财务模块的 account_account、account_account_tag 及多张中间关联表有助于理解业务模型与表命名的对应关系。资料压缩包为 1 个 PDF 文件大小约 8.07MB便于桌面端检索与离线查阅无需安装额外工具即可浏览全部结构。对正在学习 Odoo 17 数据模型、或准备进行模块二次开发的读者来说这份字典可作为日常开发中的快速参考手册减少反复翻看模型定义的时间。目前已有 133 人学习下载适合按模块逐表阅读或按需查阅。1. odoo17 数据字典已翻译为中文实施团队第一份拿来即用的资产刚接手一套带深度定制的 Odoo 17业务顾问最怕的不是功能不会配而是业务方来一句“客户编码到底存在哪个字段”。菜单翻一遍、源码搜一遍、数据库里试一遍大半天就没了。odoo17 数据字典已翻译为中文解决的就是这个痛点把 Odoo 17 内置的模型、字段、约束、选择项整理成一份能按业务口径检索的中文清单。它的价值不在罗列字段而在于让实施顾问、开发者和客户用同一套中文术语对齐需求做数据迁移、报表开发、二次改造之前先查字典不用再去翻源码猜含义。适合 Odoo 实施与二开团队尤其是要接手别人定制过的库的人。2. Odoo 17 数据字典的内容结构模型、字段类型与约束怎么排布2.1 模型与表名的映射不要只记中文名要记表名生成规则Odoo 17 的所有业务对象都叫 model模型模型名用点分命名空间表达业务归属。res.partner 表示基础资源里的业务伙伴sale.order 表示销售订单account.move 是财务凭证stock.picking 是库存调拨单。模型名转数据库表名的规则非常机械点号换成下划线。sale.order 对应 sale_orderaccount.move.line 对应 account_move_line多对多字段自动生成的中间表会以 model1_model2 的格式命名这层规则在写 SQL 报表时最容易踩坑。做数据字典时除了字段本身还要区分三类模型普通模型Model落库、抽象模型AbstractModel不落库但被继承、临时模型TransientModel用于向导。在env[ir.model].search([])的结果里transient 标记为 True 的就是向导用的临时表。很多新手把 wizard 表当成业务表去 join结果查不到数据字典里应当单列一个“是否瞬态”列来规避这个问题。2.2 字段类型与数据库存储数据字典不能只写一个类型列Odoo 17 的字段类型有十几种数据字典如果只写“类型”一个单元格下游做数据迁移的人根本不知道这个字段在数据库里长什么样。下面是我导出字典时固定使用的字段类型映射表。Odoo 字段类型数据库存储数据字典需额外记录Charvarchar长度size 属性Texttext无Integerint4无Floatnumeric精度与应用层校验规则Booleanbool默认值Selection通常是 varchar 或 int4枚举值与中文标签映射Date / Datetimedate / timestamp时区处理信息Monetarynumeric币种字段Many2one本表加_id外键列目标模型与目标模型中文名One2many不落列反向关联目标模型及反向字段Many2many自动生成中间表中间表名、目标模型Binarybytea附件用途说明Jsonjsonb结构示例这里特别要说明 One2many 和 Many2many它们在业务表单上是“一个订单有多个明细行”但在数据库里没有列要么靠反向外键要么靠中间表。字典里如果不注明开发人员拿 SQL 直接SELECT move_ids FROM sale_order就会报列不存在。2.3 字段属性required、help、compute 在字典里怎么表达导出数据字典时很多人只关注字段名类型标签却忽略 required、help、compute这三个属性在下游直接决定字段能不能手工写入。Odoo 的 required 大多在应用层校验不是数据库级 NOT NULL。这意味着绕过界面直接写库时为空的数据也能被插进去。字典里如果只写“必填是”会误导 ETL 工程师去建 NOT NULL反而把数据迁移搞挂。建议字典加一列“必填位置”按实际情况填“界面 / 数据库 / 无”。计算字段在 Odoo 17 里由 compute 定义计算方法storeTrue 才把结果落库。未落库的计算字段用 SQL 查永远报列不存在但界面字段列表里却有它。字典中需要标注 compute 与 store 两个布尔位最好把依赖字段也保留下来这样写报表的人就知道该不该 join 这个列。related 字段是另一种常见来源比如relatedpartner_id.name直接取上下游字段字典里把这条路径抄过来比让新人猜字段含义高效得多。help 文本是鼠标悬停提示通常用一段英文描述业务规则这是中文化时信息密度最高的段落。很多中文数据字典把它丢了等于丢掉了字段的完整业务口径。index 属性决定字段是否有数据库索引对后续性能排查也有价值这些都不该省。2.4 约束与索引把 SQL 约束翻成业务语言Odoo 模型的 sql_constraints 定义一个元组列表标识、SQL语句、错误消息。比如同一公司下产品名称不能重复这就是一条 UNIQUE 约束。这些约束在 information_schema 里能看到一部分但 Odoo 的错误消息里带中文提示才是业务可读的。数据字典加一列“约束说明”把 SQL 约束翻译成业务语言例如“同一公司下产品名称不能重复”业务方读得懂才能提正确需求。3. 生成 Odoo 17 数据字典原始清单Shell 脚本与直读内置表两条路线3.1 三条生成路线对比别只盯着 information_schema生成 Odoo 17 数据字典常见有三条路线先看差异再选避免白忙一场。路线能拿到拿不到或风险推荐场景Odoo Shell 调 fields_get()string、help、selection、relation、required受当前用户权限裁剪瞬态模型干扰快速核对单个模块直读 ir.model / ir.model.fields全部模型与字段定义不受权限限制selection 以文本形式存储需要解析部分 help 要二次关联全量导出做正式字典查 information_schema.columns列名、类型、约束、默认值没有业务标签和帮助文本校验字典与真实库是否一致我一般推荐组合拳先 Shell 里用 fields_get() 拿业务标签形成主字典再用 ir.model.fields 表做全量补充最后用 information_schema 做列级校验。两条腿走路能同时覆盖“界面字段”和“数据库字段”两套视角。3.2 用 Odoo Shell 导出字段清单核心脚本启动 Odoo 17 的 shell 环境后直接跑 Python注意务必用管理员账号否则 fields_get() 会因为权限裁剪少返回字段。脚本如下# 在 Odoo 17 shell 里运行的导出主程序 # 启动方式./odoo-bin shell -d your_db # 不要用业务员账号权限会裁剪字段列表 import csv # 排除系统级模型避免字典被邮件、总线、Web 框架字段灌满 IGNORE_MODEL_PREFIX (ir., base., bus., web., mail., utm.) # 每个模型都自带审计字段单独剥离后续由模板统一附加 IGNORE_FIELDS {id, display_name, create_uid, create_date, write_uid, write_date, __last_update} def serialize_selection(selection): selection 在 fields_get() 中是 list[tuple]转成可读字符串 if not selection: return return | .join(f{value}:{label} for value, label in selection) rows [] seen set() for model in env.models.values(): if model._name.startswith(IGNORE_MODEL_PREFIX): continue if model._name in seen: continue seen.add(model._name) try: metas model.fields_get() except Exception: # 抽象模型或权限不足的模型没有可读字段跳过即可 continue for fname, meta in metas.items(): if fname in IGNORE_FIELDS: continue rows.append({ model: model._name, field: fname, label: meta.get(string, ) or fname, type: meta.get(type, ), required: meta.get(required, ), help: meta.get(help, ) or , selection: serialize_selection(meta.get(selection, [])), relation: meta.get(relation, ), })这段代码的逻辑不复杂但有两个关键点env.models是模型注册表遍历它等于拿到整个 Odoo 实例的模型类fields_get()一次返回该模型全部字段元数据键是技术字段名值是元数据字典包含 string、type、help、selection、relation 等属性。seen 集合用来去重因为同一个模型在注册表里可能出现多次。3.3 写 CSV 的编码与字段序列化Excel 不乱码的细节导出的 CSV 要用 utf-8-sig 编码否则 Excel 双击打开中文全是乱码这是最常见的交付事故。写完文件后再打印统计信息方便和数据库行数做对比。# 输出 CSVutf-8-sig 保证 Excel 直接打开不乱码 out /tmp/odoo17_fields_raw.csv with open(out, w, newline, encodingutf-8-sig) as f: writer csv.DictWriter(f, fieldnameslist(rows[0].keys())) writer.writeheader() writer.writerows(rows) print(f共 {len(rows)} 条字段记录写入 {out})参数说明newline是为了避免 Windows 环境下 csv 模块写入出现空行encodingutf-8-sig会写入 BOM 头Excel 识别为 UTF-8。selection 字段被序列化成value:label | value:label的字符串翻译时可以直接在这列做替换。3.4 按模块分组模型名前缀只够做一级分类导出的扁平表格动辄上万行直接看没法用。常见做法是按模型名前缀做一级分组sale.* 归销售、account.* 归财务、stock.* 归库存、purchase.* 归采购、mrp.* 归制造。这只是近似分类因为 Odoo 的模块会互相扩展sale.order 上可能挂着 account 模块加的字段。要精确到字段归属模块需要查ir.model.data里 modelir.model.fields 的 module 记录但这些记录不一定存在。我一般把前缀分组作为默认值字段归属模块留给人工作补充不强行自动化。4. 中文翻译落地术语表驱动 选择项与帮助文本处理细节4.1 先想清楚字典翻译和界面汉化是两码事这一步不明确后面全是坑。Odoo 17 的界面标签由源码里的 string 属性和 i18n 翻译模块共同控制而数据字典中文化是把元数据里的英文文本翻译成中文输出物是 CSV、Excel 或网页文档。改字典不会让界面变成中文相反做完界面翻译也不等于就有了中文数据字典——界面翻译通常只覆盖用户可见字符串字段说明和帮助文本经常缺失。标题里说的“已翻译为中文”指文档级汉化不是界面汉化。实际操作时我固定用英文状态导出原始字段再在生成流程中把英文文本翻译成中文输出让字典与界面语言解耦。这样字典可以同时保留“英文原值”和“中文翻译”两列以后界面语言切换也不影响文档。4.2 术语表先行业务口径不定翻译必翻车数据字典中文化最大的风险不是单词看不懂而是同一个词在不同项目里叫法不同。partner 有的项目叫客户有的叫往来单位有的叫业务伙伴invoice 有的叫发票有的叫账单。如果开发按字面翻译业务顾问按自己的习惯叫字典就失去了对齐口径的意义。先定一份术语表让业务顾问确认后再批量替换。常见核心术语映射如下partner默认译“业务伙伴”若项目只用客户/供应商可整体替换sales order销售订单order line订单明细行不要只译“行”customer invoice客户发票vendor bill供应商账单product产品picking调拨单move库存移动lot批次serial number序列号术语表一旦定稿所有导入模板、报表字段、培训资料都用同一套词。这是整个中文化的基石省掉这一步后面返工成本很高。4.3 用脚本做术语替换先长词再短词避免错杀拿到第 3 章导出的原始 CSV 后写一个独立 Python 脚本做术语替换。外壳是 csv 读写核心是查表翻译函数。# 中文化脚本读取原始 CSV输出中文字典 import csv TERM_MAP [ # 顺序有讲究先长词后短词避免 order 先替换导致 order line 被二次错杀 (Sales Order Line, 销售订单行), (Purchase Order Line, 采购订单行), (Sales Order, 销售订单), (Purchase Order, 采购订单), (Replenishment Order, 补货单), (Delivery Order, 交货单), (Vendor Bill, 供应商账单), (Customer Invoice, 客户发票), (Business Partner, 业务伙伴), (Partner, 客户/供应商), (Product Variant, 产品变体), (On Hand Quantity, 现有库存), (Unit of Measure, 计量单位), ] def translate(text): 按 TERM_MAP 顺序替换未匹配的原文保留后续人工处理 if not text: return text for en, zh in TERM_MAP: if en.lower() in text.lower(): # 简单示例严谨做法是正则忽略大小写并限定词边界 text text.replace(en, zh) return text with open(odoo17_fields_raw.csv, r, encodingutf-8-sig) as f: reader csv.DictReader(f) rows list(reader) for row in rows: row[label_zh] translate(row.get(label, )) row[help_zh] translate(row.get(help, )) with open(odoo17_fields_zh.csv, w, newline, encodingutf-8-sig) as f: writer csv.DictWriter(f, fieldnamesrows[0].keys()) writer.writeheader() writer.writerows(rows)这段代码里 TERM_MAP 的顺序就是命门。先替换 Sales Order Line再替换 Sales Order最后再处理短词因为文本“Sales Order Line”如果先被 Sales Order 替换会变成“销售订单 Line”长词条目就永远匹配不上了。脚本还应该输出一份未命中清单把 label_zh 或 help_zh 仍含英文单词的行挑出来人工翻译后再合入这是质量闸门。4.4 选择项与帮助文本别把枚举 value 也翻译了Selection 字段的翻译要特别注意value 是数据库里实际存储的技术枚举值dict 里 dictionary 的 key 不能动。以 sale.order 的 state 字段为例数据库存的是 draft、confirmed、done中文翻译只作用在标签上技术值英文标签中文标签draftQuotation报价草稿confirmedConfirmed Order已确认订单doneDone已完成cancelCancelled已取消帮助文本通常是完整英文句子机器翻译容易把业务规则翻译得模棱两可。我一般只替换其中的核心术语再人工重写保证“在什么条件下字段可见、影响哪些下游流程”这些关键信息不失真。验收标准也很简单一条模型记录里如果有模型中文名、字段中文标签、帮助中文说明三样都齐才算译完只翻译标签不翻译帮助业务顾问依然读不懂。5. 数据字典翻译与导出的避坑实录五个高频问题排查5.1 字段导不出来权限黑匣子怎么破现象用业务员账号连 shell 导出sale.order 下明显少了很多字段例如 partner_shipping_id 不在列表里。原因fields_get() 在 Odoo 17 里会按当前用户组的字段访问权限裁剪可见字段。业务员账号看不到隐藏字段导出结果自然不全这属于权限黑匣子。解决导出字典一律用管理员账号执行。如果管理员账号也不行直接查 ir_model_fields 表该表存储系统全量字段定义不受权限影响SELECT f.name, f.field_description, f.ttype FROM ir_model_fields f JOIN ir_model m ON f.model_id m.id WHERE m.model sale.order AND f.name IN (partner_shipping_id, partner_id);这条 SQL 返回 sale.order 上两个字段的技术名、英文标签和类型是对照导出结果是否完整的快捷方式。字段总数对不上时优先怀疑权限而不是怀疑脚本有 bug。5.2 compute 字段与自动化字段要不要收进字典现象字段清单里有 product_qty但数据库表里没有同名列开发写报表 SQL 一直报错。原因product_qty 是典型的非存储计算字段值由 move 行聚合算出ORM 查询时即时计算不落数据库。解决字典必须加“计算 / 存储”两列。来源是 compute 的标“计算”storeTrue 才标“存储”两列都为否的字段在 SQL 报表里不要直接引用。翻译时也要把 compute 的依赖字段写出来方便写 SQL 的人改取数逻辑。自动化字段不要整体丢弃去掉后字典会漏掉界面上一大半可读字段业务方会以为系统没这功能。5.3 术语替换翻车“Order Point”被译成“订单点”现象库存模块里 Order Point 被自动替换成“订单点”业务方完全看不懂。实际上这是补货规则里的订货点。原因术语替换用简单字典且顺序不对Order 先被替换后续更长的 Order Point 条目已经无法匹配。解决替换前按词条长度降序排序凡是包含 Order、Product、Partner 等高频词的短语全部人工检查一遍严谨做法是用正则忽略大小写并限定词边界。这次翻车直接导致库存模块的中文字典返工两天血泪教训。5.4 字典汉化后界面不生效文档资产与界面翻译的边界现象同事拿到中文数据字典后以为把 string 改成中文就能在界面看到中文结果 Odoo 17 界面还是英文。原因数据字典是文档资产界面标签由源码里的 string 与 i18n 翻译模块共同控制。改字典文件不会触发界面变化。解决目标是界面中文化时走翻译模块的导入导出流程把 PO 文件翻译后再导入或者直接改字段定义的 string 属性并升级模块。字典中文化是配合文档和需求对齐用的不能替代界面汉化。交付时要把这个边界写清楚避免业务方误判项目进度。5.5 Many2one 字段只有目标模型名业务方看不懂现象partner_id 的类型是 many2onerelation 是 res.partner业务方不知道 res.partner 里能选出什么。原因fields_get() 的 relation 只给目标模型技术名不解释目标模型的业务含义。res.partner 对没接触过 Odoo 的人来说就是黑话。解决在字典里增加“目标模型中文名”列用与术语表一致的映射补齐res.partner 对应业务伙伴/客户/供应商res.company 对应公司uom.uom 对应计量单位product.product 对应产品变体。这样导入数据的人一看就知道该去哪张表取可选值不用再翻模块结构图。6. 验收与进阶把中文数据字典用成团队的长期资产拿到中文数据字典后别急着全员铺开先做一次抽样验收。我习惯随机抽 10 个当前正在做的模块字段逐个到界面和数据库两边核对数据库里有没有这个列、界面标签是否一致、帮助文本是否真的翻译到位。三处对不上就回头查是导出脚本过滤错了还是替换脚本漏词。另一个快速计数校验是执行字段总数对比把第 3 章导出的 CSV 行数和数据库结果比对差得多了说明黑名单过滤或权限配置有问题。进阶使用上术语表不要散在脚本里。把它存成独立的 YAML 文件放进项目仓库和字典生成脚本一起做版本管理。下次从 Odoo 16 升级到 Odoo 17或者老库导数据到新库时拿两份 CSV 做字段级 diff重点看新增字段、删除字段和类型变更能省下大量排查时间。这时候数据字典就不再是一次性交付物而是跟着项目走的技术档案。最后一条个人教训数据字典必须连着业务口径一起交付不要只交一张字段表。有一回做库存模块的数据导入我手里的字典没标 onchange 触发字段导入模板把数量列放错差点覆盖整行库存。从那以后我在字典里专门留一列“触发动作”凡是 onchange 作用在哪些字段上都写清楚数据迁移和导入模板设计先看这一列后面很少再翻车。如果你的团队正在做 Odoo 17 实施把这份中文数据字典当活文档维护而不只是查一次就丢一边希望帮到你。本文还有配套的精品资源点击获取