有没有办法在Redshift中的表之间复制或克隆授权?

时间:2019-04-30 15:21:59

标签: sql amazon-redshift grant

由于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,但这似乎不是最简单的操作。

1 个答案:

答案 0 :(得分:0)

我不想将其标记为答案,因为我敢肯定有人对此有更好的方法,但是我能够编写脚本来查看两个表之间的读取权限差异并生成授权语句:

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;```