You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Policy与RLS实现表查询自动过滤deleted=true的行

RLS 过滤已删除行实现方案

RLS是实现该需求的最优方案,你写的策略逻辑本身没有问题,未生效通常是几个常见的配置疏漏导致的。

常见不生效原因排查

  • 执行查询的账号是超级用户:PostgreSQL超级用户默认会绕过所有RLS规则,你可以切换普通用户测试,或者手动开启当前会话的RLS强制校验:set row_security = on;
  • 未对表所有者开启RLS强制校验:默认表的创建者不受RLS限制,如果你需要所有者也遵守策略,你写的force row level security配置已经满足该要求,确认该语句执行成功即可。
  • 数据库全局RLS开关未开启:执行show row_security;检查参数值是否为on,默认该配置是开启状态,若为off需要修改postgresql.conf配置文件重启生效。

完整正确实现步骤

-- 1. 先确保deleted字段有默认值,避免NULL值导致的逻辑异常
ALTER TABLE my_table ALTER COLUMN deleted SET DEFAULT false;

-- 2. 开启表的行级安全
ALTER TABLE my_table ENABLE ROW LEVEL SECURITY;
-- 可选:强制表所有者也受RLS限制,不需要可以删除该行
ALTER TABLE my_table FORCE ROW LEVEL SECURITY;

-- 3. 创建查询过滤策略,你原来的逻辑可以正常使用
CREATE policy hide_deleted_rows ON my_table
FOR SELECT TO public USING (deleted IS NOT true);

配置完成后用普通用户执行select * from my_table where deleted = true;就会返回空结果,符合你的预期。

为什么不推荐用触发器实现

PostgreSQL本身没有BEFORE SELECT类型的触发器,你无法通过触发器直接拦截SELECT查询做行过滤。如果不用RLS,替代方案是创建带过滤条件的视图,给所有用户开放视图查询权限、收回基表的直接访问权限,但这种方案需要改上层业务的查询逻辑,也容易出现权限漏配的问题,远不如RLS易用可靠。

内容的提问来源于stack exchange,提问作者Denis Yakovenko

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 05:39:00