由于Redshift的仅附加属性,我们经常需要合并表以删除重复记录并显示最新版本的记录。要准备此过程,将重命名基表并创建其副本。将执行脚本以扫描插入表并将最新的唯一记录移动到新的基表中。但是,如果表在此过程开始之前已经运行了一段时间,那么在创建克隆时,表上可能会有未授权的授权。
我们经常没有原始表DDL,虽然我们能够通过https://github.com/awslabs/amazon-redshift-utils/blob/master/src/AdminViews/v_generate_tbl_ddl.sql获取它,但这不会生成任何授权的表定义。
有没有办法复制具有就地授予的表,或生成一个脚本来创建基于旧表的授权?
尝试过使用https://github.com/awslabs/amazon-redshift-utils/blob/master/src/AdminViews/v_generate_tbl_ddl.sql,但这不会生成任何grant语句,只会生成set owner语句。
也看了has_table_privilege
,但这似乎不是最简单的行动方案。
我不想将此标记为答案,因为我确信有人有更好的方法,但我能够编写一个脚本来查看两个表之间的读权限差异并生成grant语句:
SELECT
'GRANT SELECT ON TABLE ' || admin_table.schemaname || '.' || admin_table.objectname || ' to ' || old_table.usename || ';' AS grant_statement
FROM (
SELECT *
FROM (
SELECT
schemaname
,objectname
,usename
,has_table_privilege(usrs.usename, fullobj, 'select') AND has_schema_privilege(usrs.usename, schemaname, 'usage') AS sel
FROM (
SELECT schemaname, 't' AS obj_type, tablename AS objectname, schemaname + '.' + tablename AS fullobj FROM pg_tables
UNION
SELECT schemaname, 'v' AS obj_type, viewname AS objectname, schemaname + '.' + viewname AS fullobj FROM pg_views
) AS objs
, (SELECT * FROM pg_user) AS usrs
ORDER BY fullobj
)
WHERE (sel = true)
AND schemaname = '{schema_name}' AND objectname = '{old_table_name}') AS old_table
FULL OUTER JOIN (
SELECT *
FROM (
SELECT
schemaname
,objectname
,usename
,has_table_privilege(usrs.usename, fullobj, 'select') AND has_schema_privilege(usrs.usename, schemaname, 'usage') AS sel
FROM (
SELECT schemaname, 't' AS obj_type, tablename AS objectname, schemaname + '.' + tablename AS fullobj FROM pg_tables
UNION
SELECT schemaname, 'v' AS obj_type, viewname AS objectname, schemaname + '.' + viewname AS fullobj FROM pg_views
) AS objs
, (SELECT * FROM pg_user) AS usrs
ORDER BY fullobj
)
WHERE (sel = true)
AND schemaname = '{schema_name}' AND objectname = '{new_table_name}') AS new_table
ON old_table.schemaname = new_table.schemaname
AND old_table.sel = new_table.sel
AND old_table.usename = new_table.usename
JOIN (
SELECT *
FROM (
SELECT
schemaname
,objectname
,usename
,has_table_privilege(usrs.usename, fullobj, 'select') AND has_schema_privilege(usrs.usename, schemaname, 'usage') AS sel
FROM (
SELECT schemaname, 't' AS obj_type, tablename AS objectname, schemaname + '.' + tablename AS fullobj FROM pg_tables
UNION
SELECT schemaname, 'v' AS obj_type, viewname AS objectname, schemaname + '.' + viewname AS fullobj FROM pg_views
) AS objs
, (SELECT * FROM pg_user) AS usrs
ORDER BY fullobj
)
WHERE (sel = true)
AND schemaname = '{schema_name}' AND objectname = '{new_table_name}') AS admin_table
ON admin_table.usename = '{admin_user}'
WHERE new_table.usename IS NULL
AND old_table.sel IS true;```