Есть ли способ скопировать или клонировать гранты между таблицами в Redshift? - PullRequest
2 голосов
/ 30 апреля 2019

В связи с тем, что 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, но это не генерирует никаких операторов предоставления, только заявление о владельце набора.

Также изучили has_table_privilege, но, похоже, это не самый простой способ действий.

1 Ответ

0 голосов
/ 01 мая 2019

Я не хочу помечать это как ответ, так как уверен, что у кого-то есть лучший подход к этому, но я смог написать скрипт для просмотра различий разрешений на чтение между двумя таблицами и генерации операторов предоставления:

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;```
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...