【发布时间】:2015-11-22 21:46:49
【问题描述】:
我有一个可更新的 postgres 视图,它公开了一个 person 表。该视图隐藏了一些私人数据,例如电子邮件。插入时,我希望用户能够为该私有数据插入值。使用规则或触发器来获得此功能会更好吗?
经过一些测试,我似乎无法使用触发器插入视图中未定义的列。
【问题讨论】:
标签: postgresql triggers views
我有一个可更新的 postgres 视图,它公开了一个 person 表。该视图隐藏了一些私人数据,例如电子邮件。插入时,我希望用户能够为该私有数据插入值。使用规则或触发器来获得此功能会更好吗?
经过一些测试,我似乎无法使用触发器插入视图中未定义的列。
【问题讨论】:
标签: postgresql triggers views
一种可能的方法是使用权限而不是视图来公开列的子集。
例如,给定表格
create table person(
first_name text,
last_name text,
email text
);
您可以向用户授予以下权限:
grant select(first_name, last_name) on person to someuser;
grant insert on person to someuser;
这就是它的工作原理:
postgres=> insert into person values('Foo','Bar','foo@bar.com');
INSERT 0 1
postgres=> select * from person;
ERROR: permission denied for relation person
postgres=> select first_name, last_name from person;
first_name | last_name
------------+-----------
Foo | Bar
(1 row)
当然,只能基于“每个用户”。
另一种方法是使用定义为“安全定义器”的函数。这指定该函数将以创建它的用户的权限执行。
所以你可以定义一个函数直接向表中插入数据;定义者必须有插入权限:
create function person_insert(first_name text, last_name text, email text)
returns void
security definer
as $$
insert into person(first_name, last_name, email) values ($1, $2, $3);
$$ language sql;
然后其他用户可以调用它而无需自己的插入权限:
postgres=> insert into person(first_name, last_name, email) values ('foo', 'bar', 'foo@bar.com');
ERROR: permission denied for relation person
postgres=> select person_insert('foo','bar','foo@bar.com');
people_insert
---------------
(1 row)
postgres=> select * from person_view;
first_name | last_name
------------+-----------
Foo | Bar
(1 row)
【讨论】: