昨天在工作中遇到一个问题:
由于这是odoo12的架构,所以新加的这个字段还是个计算字段。
逻辑是: 客户优先引用“出运要求”关联的客户,如果这个客户没有值,则取 “采购合同” 关联的客户字段。这张表已经有13000条数据了。
即使增加了这个客户的计算逻辑,也无法触发这个计算字段。
@api.depends('delivery_order_id', 'purchase_order') def _compute_customer_id(self): for record in self: if record.delivery_order_id and record.delivery_order_id.customer_id: # 如果出运要求存在并且有客户信息 record.customer_id = record.delivery_order_id.customer_id # _logger.debug('出运要求的客户: %s', record.customer_id) elif record.purchase_order_id and record.purchase_order.customer_id: # 如果出运要求没有客户信息,则取采购订单的客户信息 record.customer_id = record.purchase_order.customer_id # _logger.debug('采购订单: %s', record.purchase_order) # _logger.debug('采购订单的客户: %s', record.purchase_order.customer_id) else: # 如果两个字段都为空,设置 customer_id 为空 record.customer_id = False # _logger.info('未找到客户信息')
所以下面有两个方式:
1、通过odoo的shell 来运行Py代码触发:
# 查找所有 purchase.account.invoice 记录 records = env['purchase.account.invoice'].search([]) # 批量触发 _compute_customer_id 方法来重新计算 customer_id 字段 records._compute_customer_id()
如果这个字段是可存储的,那么还要提交到数据库
env.cr.commit()
但是这个shell环境,我测试了好多次,也没有成功。所以就用了下面的方法
2、执行SQL来触发
UPDATE purchase_account_invoice AS pai -- 更新 purchase_account_invoice 表,设置别名为 pai,以便在后续引用该表时简化代码书写。 SET customer_id = COALESCE( -- 设置 customer_id 字段的值,优先级按以下两种情况决定: -- 使用 COALESCE 函数在多个选项中选择第一个非空值。 (SELECT delivery_order.customer_id FROM delivery_order WHERE delivery_order.id = pai.delivery_order_id), -- 如果 delivery_order_id 字段有值: -- 在 delivery_order 表中查找匹配的 delivery_order.id 值对应的 customer_id, -- 并将其作为 customer_id 的值。 (SELECT purchase_order.customer_id FROM purchase_order WHERE purchase_order.id = pai.purchase_order) -- 如果 delivery_order_id 字段为空,但 purchase_order 字段有值: -- 在 purchase_order 表中查找匹配的 purchase_order.id 值对应的 customer_id, -- 并将其作为 customer_id 的值。 ) WHERE pai.delivery_order_id IS NOT NULL OR pai.purchase_order IS NOT NULL; -- 仅当 delivery_order_id 或 purchase_order 字段存在有效值时才进行更新。
用SQL方法快速,缺点是:无法执行orm中的方法保持数据的一致性,所以要清缓存。最直接有效果的方法是重启odoo服务。
SQL 知识点外延
-
COALESCE
函数:COALESCE
是 SQL 中常用的函数,用于从多个表达式中返回第一个非空值。例如,COALESCE(A, B, C)
会依次检查A
、B
、C
,并返回第一个非空的值。如果所有值都为空,则返回 NULL。- 这是简化条件判断的一种方式,适用于需要多层判断优先级的场景。
-
JOIN
和子查询的对比:- 在这段代码中,
COALESCE
使用了子查询的方式来查找客户信息,分别从delivery_order
和purchase_order
表中获取。 - 另一种方式是使用
JOIN
来完成同样的操作,但由于此处使用的COALESCE
需要优先级判断(即优先选择第一个非空值),JOIN
可能不够简洁或不易表达这种逻辑。
- 在这段代码中,
-
条件更新:
WHERE
子句控制了UPDATE
的执行条件,确保只有delivery_order_id
或purchase_order
不为空的记录才会被更新。这在数据表的批量更新操作中非常重要,因为能够有效避免对无关记录的更新,保证数据处理的准确性。
-
外键关联与冗余数据更新:
- 这种方式更新
customer_id
字段通常是为了优化查询性能。虽然customer_id
存在于其他表中,但通过冗余存储在purchase_account_invoice
表中,减少了频繁查询其他表的需求,适合高频访问数据的场景。
- 这种方式更新
-
性能优化:
- 对大量数据进行批量更新时,SQL 的写法会影响性能。使用
COALESCE
和条件限制更新的方式可以显著减少更新的记录数量,这在大规模数据处理中尤为重要。
- 对大量数据进行批量更新时,SQL 的写法会影响性能。使用
通过上述 SQL 查询, 可以将关联表中的信息冗余存储在当前表中以加速查询,同时可以灵活控制字段优先级和更新条件,实现数据优化。
标签:customer,purchase,ODOO12,id,delivery,record,刷新,强制,order From: https://www.cnblogs.com/lyt263/p/18517180