开启Row Level Security的表更新行违反RLS策略如何解决?
RLS更新报错问题排查与修复
问题根因
PostgreSQL行级安全的UPDATE操作分为两步校验:
USING子句校验更新前的旧行是否允许被操作,你的配置中using(true)满足要求,旧行校验可正常通过WITH CHECK子句校验更新后的新行是否符合权限规则,你实际执行的复现SQL中UPDATE策略遗漏了WITH CHECK子句,此时PostgreSQL会自动套用所有生效的永久策略条件校验新行。你配置的SELECT策略要求deleted is false,而软删除操作更新后deleted = true,不符合隐含校验规则,因此触发报错。
你最初贴的RLS配置示例中UPDATE策略是带with check (true)的,但实际执行的复现SQL遗漏了该配置,是问题的直接诱因。
修复方案
补全UPDATE策略的WITH CHECK子句,显式允许更新后的行符合任意条件即可:
create policy my_table_update_policy on my_table for update to public using (true) with check (true);
如果需要更严谨的权限控制,可根据业务调整WITH CHECK的条件,例如仅允许修改deleted字段、禁止变更其他核心字段:
create policy my_table_update_policy on my_table for update to public using (true) with check ( name = old.name AND deleted IS NOT NULL );
内容的提问来源于stack exchange,提问作者Denis Yakovenko
相关产品推荐
相关产品推荐

