问题描述
我需要一个事件触发器,该触发器在每次创建架构时都向特定用户提供CRUD访问权限。
这是我的尝试:
CREATE FUNCTION trigger_after_create_schema()
RETURNS event_trigger LANGUAGE plpgsql
AS $$
BEGIN
GRANT USAGE ON SCHEMA TG_TABLE_SCHEMA TO "api_server";
GRANT SELECT,INSERT,UPDATE,DELETE ON ALL TABLES IN SCHEMA TG_TABLE_SCHEMA TO "api_server";
END;
$$;
CREATE EVENT TRIGGER after_create_schema
ON ddl_command_end
WHEN TAG IN ('CREATE SCHEMA')
EXECUTE PROCEDURE trigger_after_create_schema();
这将导致以下错误:
ERROR: no schema has been selected to create in
sql state: 3F000
我以超级用户身份在pgAdmin
中执行此操作,因此我认为这不是权限问题。
我想念什么?
编辑
CREATE SCHEMA
语句看起来像这样:
CREATE SCHEMA "tenant" AUTHORIZATION "auth_server";
auth_server
是具有创建架构特权的非超级用户。
作为一种解决方法,我可以赋予auth_server
CREATEROLE
特权并在与GRANT
相同的事务中执行CREATE SCHEMA
语句,但是对我来说这似乎不是最佳选择
auth_server
在这种情况下不需要CREATEROLE
,并且还需要破解第三方程序包的源代码,即。 django_tenants
。
解决方法
赠款不能直接在过程/函数中运行,您需要动态SQL。试试:
create or replace
function trigger_after_create_schema()
returns event_trigger
language plpgsql
as $$
declare
k_grant_usage constant text =
'grant usage on schema % to "api_server"';
k_grant_dml constant text =
'grant select,insert,update,delete on all tables in schema tg_table_schema to "api_server"';
l_ddl_stmt text;
begin
l_ddl_stmt = format(k_grant_usage,tg_table_schema);
raise notice 'Running statement: %',l_ddl_stmt;
execute l_ddl_stmt;
l_ddl_stmt = format(k_grant_dml,l_ddl_stmt;
execute l_ddl_stmt;
end;
$$;
但是,您收到的错误消息不在触发器中。它指示 CREATE SCHEMA ... 命令无效。