Odoo 如何用 populate 命令基于现有记录批量复制数据生成测试库

📅 发布时间:2026/9/13 10:45:15
Odoo 如何用 populate 命令基于现有记录批量复制数据生成测试库
Odoo 如何用 populate 命令基于现有记录批量复制数据生成测试库【免费下载链接】odooOdoo. Open Source Apps To Grow Your Business.项目地址: https://gitcode.com/GitHub_Trending/od/odoo如果你手上已有一个带少量真实数据的 Odoo 数据库想快速得到一份数据量放大若干个版本的测试/演示库而不必手工录入Odoo 内置的populate命令就是为此设计的它以数据库中现有记录为模板做批量复制duplication同时维护外键引用一致性、处理唯一约束字段并优化大批量插入性能。实现入口在 odoo/cli/populate.py核心 SQL 逻辑在 odoo/tools/populate.py。本文适用的前提是你可以访问 Odoo 源码树使用其中的 odoo-bin 启动器目标数据库已经初始化完成且待放大的模型里至少已有部分记录空表没有模板可复制会被直接跳过-d/--database只能指定一个数据库命令检测到多个数据库时直接退出并报错-d/--database/db_name has multiple database, please provide a single one。基本命令与三个参数populate是odoo-bin的一个子命令参数定义在 odoo/cli/populate.py 中共三个参数默认值作用--factors10000每个模型的复制倍数。可以传一个值也可以按模型顺序传逗号分隔的多个值最后一个值会传递给其余未单独指定的模型--modelsres.partner,product.template,account.move,sale.order,crm.lead,stock.picking,project.task要放大的模型列表逗号分隔--sep_char/text 字段变化时追加的单字符分隔符必须是单个 Unicode 字符否则抛ValueError: Separator must be a single Unicode character.factor的语义在帮助文本里写得很明确factor 为 3 表示该模型的记录被复制 3 份最终达到原有数据量的 4 倍3 原始 1 4x。命令内部会自动追加--no-http即不会拉起 HTTP 服务。最短的完整命令./odoo-bin populate -d my_test_db --models res.partner,product.template --factors 3,10 --sep _这条命令的含义res.partner复制 3 份变成 4xproduct.template复制 10 份变成 11xchar/text 字段用_作为变化后缀。如果不关心默认模型列表也可以只给一个 factor它会被所有模型共用./odoo-bin populate -d my_test_db --factors 5此时模型列表和 factor 都取默认值7 个默认模型、每个 factor 10000。默认 factor 数值很大只是用来满足 demo 场景的量级需求如果你的库较小请按上例显式给一个能接受的倍数。命令实际做了什么odoo/tools/populate.py 的模块文档说明了整个复制策略理解它有助于判断结果是否符合预期引用完整性Many2one 字段会被重新映射到对应的副本记录One2many 通过反向 Many2one 隐式完成Many2many 通过复制关系表完成。这样复制出来的销售订单仍指向复制出来的客户、订单行等而不是全部指向同一批原始记录。字段变化char/text 字段会被追加变化后缀即--sep字符以绕开唯一约束、并让name_search检索有区分度date/datetime 字段会在一个时间窗口内分布开硬上限是最近 4 年避免复制记录日期过早html 字段为了简单不做变化直接原样复制。性能优化插入前临时删除目标表上的普通索引主键索引和唯一索引保留以维持约束插入后按原定义恢复同时用SET session_replication_role TO replica关闭外键检查。依赖顺序带_inherits的模型会先复制被委托的模型X2many 关系另一端的模型即使没出现在--models里也会继承当前模型的 factor 一并被复制例如防止出现有订单但没有订单行的脏数据。序列修正复制完成后用SETVAL把对应表的 id 序列推进到新的最大 id。执行与结果验证运行后关注日志中这几条均来自 odoo/tools/populate.py 与 odoo/cli/populate.py 实际输出的日志语句Populating model 模型名 N times...开始处理某个模型N 即该模型的 factorDropping indexes on table 表名.../Adding indexes back on table 表名...索引临时移除与恢复结束时输出Populated models [模型列表] (total: X.XXXs)表示全部完成并给出总耗时。判断结果是否如预期可以用--factors帮助文本给出的量级关系核对某个模型的最终记录数应为「原始记录数 × (factor 1)」。例如对res.partner使用 factor 3命令前后各统计一次该表行数应为 4 倍关系char/text 唯一字段的副本会带上_后缀可顺带抽查确认。限制与异常现象以下行为都在源码中有明确定义遇到时不必视为故障权限不足时的降级如果当前 pg_role 没有权限执行SET session_replication_role TO replica命令会回滚事务、跳过关闭外键检查这一优化后重试并打印警告日志Cannot ignore Fkey constraints during insertion due to insufficient privileges for current pg_role. ... The bulk insertion will be vastly slower than anticipated.——命令继续执行只是明显变慢。空模型被跳过模型表里没有任何记录时has_records检查不通过该模型不复制因为没有模板。POS 性能测试里的注释也印证了这一点The product.template model must contain at least one record before it can be populated.transient 与 abstract 模型被过滤即使写进了--models也会被自动剔除。日期窗口date/datetime 的分布范围被限制在最近 4 年内MIN_DATETIME/MAX_DATETIME常量不会把复制记录的时间推到更早。可重入命令执行前会先对已有行的 char/text 字段做一轮更新UPDATE ... ROW(...)允许对同一数据库重复运行 populate 而不因重复的后缀逻辑产生混乱。可选在 Python/测试代码中直接调用Populate.populate是类方法签名见 odoo/cli/populate.pypopulate(env, modelname_factors: dict[str, int], separator_code: int)。addons/point_of_sale/tests/test_performances.py 展示了典型用法——按目标总量 ÷ 现有量 − 1算出 factorfrom odoo.cli.populate import Populate before_count self.env[model_name].search_count([]) if not before_count: return False populate_count round(total_count / before_count) - 1 Populate.populate(self.env, {model_name: populate_count}, 1)注意第三个参数separator_code是传给ord()后的字符码值CLI 里由ord(opt.separator)得到上面的1是该测试文件中使用的示例取值。如果你的测试目标模型必须至少存在一条记录见上文空模型限制先判断before_count再调用。如果你的场景只是把现有数据库放大 N 倍做压测或演示主路径就是开头的单条./odoo-bin populate -d 库名命令--models、--factors、--sep三个参数足以覆盖文档中说明的全部可控行为。【免费下载链接】odooOdoo. Open Source Apps To Grow Your Business.项目地址: https://gitcode.com/GitHub_Trending/od/odoo创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考