Tortoise ORM:bulk_create的update_fields与on_conflict区别及必填原因
在Tortoise ORM中执行Upsert时为何必须同时指定
on_conflict和update_fields? 问题描述
在Tortoise ORM中执行upsert操作时,需要使用bulk_create方法并同时传入on_conflict和update_fields参数,示例代码如下:
await Users.bulk_create(users_list, on_conflict=fields_list, update_fields=fields_list)
官方文档缺乏这两个参数的差异示例与深度说明,却强制要求同时设置,请问这是为什么?
解答
这两个参数承担完全不同的职责,Tortoise强制同时设置是为了明确upsert操作的核心逻辑边界:
on_conflict:定义冲突判定规则,也就是数据库依据哪些字段判断待插入数据已存在(触发冲突)。比如传入["email"],数据库会检查待插入数据的email字段是否已存在于表中,存在则触发upsert的更新逻辑。update_fields:定义冲突发生后要更新的字段列表。它和on_conflict可以是不同集合,比如用email判断冲突,但冲突发生后只更新nickname和last_login字段。
官方强制同时设置,本质是避免模糊操作:只传on_conflict的话,系统不知道冲突后要更新哪些字段;只传update_fields的话,系统不知道用什么规则判定冲突。哪怕两个参数值相同(像示例里那样),也是明确告诉系统:用这些字段判定冲突,冲突后就更新这些字段本身。
举个实际场景的例子:
假设用户表有id、email、nickname、score字段,要实现「用email判断用户是否存在,存在就更新nickname和score」,代码应写为:
await Users.bulk_create( users_list, on_conflict=["email"], update_fields=["nickname", "score"] )
这种场景下两个参数差异明显,能体现各自作用——官方文档没给这类差异示例确实容易让人困惑,但强制同时传是为了确保upsert逻辑的明确性,避免隐式行为导致的数据意外。
内容的提问来源于stack exchange,提问作者Igor Alex
相关产品推荐
相关产品推荐

