Postgres事件触发器给出“错误:尚未选择要创建的架构”

问题描述

我需要一个事件触发器,该触发器在每次创建架构时都向特定用户提供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 ... 命令无效。