第二十二章 序列号

篇别:第三篇 数据库与数据管理

本章学习目标

  • 能创建 ir.sequence 并在 模型 create / 默认值 中生成编号。
  • 理解 前缀、后缀、步长、填充、下一编号 字段含义。
  • 能配置 多公司序列按日期分段(use_date_range) 思路。
  • 了解 高并发下跳号导入数据 时的冲突处理。

导读:序列号 = 可读性与唯一性

业务上常需要 订单号、借阅单号、凭证号人类可读且大体递增 的标识。数据库 SERIAL 只能保证整数;ir.sequence 在应用层维护 格式化的下一个值,并支持 多公司、按年重置 等规则。


22.1 ir.sequence

22.1.1 知识要点

  • code:程序中用 next_by_code('my.code') 查找序列。
  • prefix / suffix:可含 时间占位(如 %(y)s%(month)s,以文档为准)。
  • padding:数字零填充宽度。
  • number_next:下一数值。
  • implementationstandard(数据库锁)与 no_gap(实验性/特殊,慎用性能)。

22.1.2 案例

数据文件定义

<record id="seq_library_book" model="ir.sequence">
  <field name="name">图书编码</field>
  <field name="code">library.book.ref</field>
  <field name="prefix">B</field>
  <field name="padding">5</field>
  <field name="number_next">1</field>
</record>

模型中使用

@api.model_create_multi
def create(self, vals_list):
    for vals in vals_list:
        if vals.get('ref', _('新建')) == _('新建'):
            vals['ref'] = self.env['ir.sequence'].next_by_code('library.book.ref') or _('新建')
    return super().create(vals_list)

或使用 fields.Char(copy=False, default=lambda self: ...)

22.1.3 截图占位

图 22-1 ir.sequence 表单

22.1.4 本节练习

  1. 实操:创建图书时 自动 refB00001 递增。
  2. 简答next_by_code 返回 False 时常见原因?
  3. 判断:同一 code 可对应多条 ir.sequence 记录且随机取一条。( )

参考答案提示:2. 未安装数据、code 拼写错误、序列未关联公司筛选失败。3. 错,通常唯一业务逻辑。


22.2 编号规则

22.2.1 知识要点

  • 多公司:序列上 company_idnext_by_code当前公司上下文 下解析。
  • 按年/月重置use_date_range + 子序列ir.sequence.date_range);每年 number_next 重置。
  • 步长number_increment 默认 1;跳号在回滚、并发下 可接受(财务连续号需业务确认)。

22.2.2 案例

两家公司各维护 SO 序列:prefix 相同但 company_id 不同,互不抢号

22.2.3 截图占位

图 22-2 多公司序列 next

22.2.4 本节练习

  1. 简答:高并发下序列 gap 是否可接受?哪些行业 不可接受
  2. 实操:配置 按年 前缀 INV/%(year)s/(语法以文档为准)。

22.3 导入与冲突

22.3.1 知识要点

  • 批量导入 固定 ref 可能 与序列下一值冲突;导入后应 number_next = max(existing)+1
  • 迁移脚本UPDATE ir_sequence SET number_next = ...

22.3.2 案例

-- 演示:迁移后对齐下一编号(须在维护窗、备份后执行)
SELECT MAX(CAST(SUBSTRING(ref FROM 2) AS INTEGER)) FROM library_book WHERE ref ~ '^B[0-9]+$';

22.3.3 本节练习

  1. 实操:写 post_init_hook 根据现有最大 ref 校正 number_next(Python 优先)。

本章综合练习

  1. 设计借阅单号 LO/2026/00001每年重置;写出序列与 prefix 思路。
  2. 导入:CSV 导入 5000 条带 ref,如何避免与序列 撞号
  3. 拓展:阅读 no_gap 序列说明(若有),一句话记录风险。
  4. 多公司:同一 code两公司number_next 独立吗?如何验证?

本章对应白皮书目录:第二十二章 序列号。