Я не хочу помечать это как ответ, так как уверен, что у кого-то есть лучший подход к этому, но я смог написать скрипт для просмотра различий разрешений на чтение между двумя таблицами и генерации операторов предоставления:
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;```