删除 Redshift 架构中的所有表 - 不删除权限

Posted

技术标签:

【中文标题】删除 Redshift 架构中的所有表 - 不删除权限【英文标题】:Drop all tables in a Redshift schema - without dropping permissions 【发布时间】:2019-08-16 22:39:20 【问题描述】:

我有兴趣删除 Redshift 架构中的所有表。即使这个解决方案有效

DROP SCHEMA public CASCADE;
CREATE SCHEMA public;

对我有好处,因为它也放弃了 SCHEMA 权限。

类似的解决方案

DO $$ DECLARE
r RECORD;
BEGIN
    -- if the schema you operate on is not "current", you will want to
    -- replace current_schema() in query with 'schematodeletetablesfrom'
    -- *and* update the generate 'DROP...' accordingly.
    FOR r IN (SELECT tablename FROM pg_tables WHERE schemaname = current_schema()) LOOP
        EXECUTE 'DROP TABLE IF EXISTS ' || quote_ident(r.tablename) || ' CASCADE';
    END LOOP;
END $$;

据此线程报告How can I drop all the tables in a PostgreSQL database? 将是理想的。不幸的是,它不适用于 Redshift(显然不支持 for loops)。

有没有其他解决方案来实现它?

【问题讨论】:

在集群外部用 python 或其他脚本语言编写循环? 【参考方案1】:

运行此 SQL 并将结果复制并粘贴到您的 SQL 客户端上。 如果您想以编程方式执行此操作,则需要围绕它构建一些代码。

SELECT 'DROP TABLE IF EXISTS ' || tablename || ' CASCADE;' 
FROM pg_tables 
WHERE schemaname = '<your_schema>'

【讨论】:

能否请您正确格式化 SQL 查询以提高答案的可读性?【参考方案2】:
SELECT 'DROP TABLE IF EXISTS ' 
       || table_name 
       || ' CASCADE;' 
FROM   information_schema.tables 
WHERE  table_schema = '<your_schema>' 
       AND table_name LIKE '<%condition%>' 

【讨论】:

您好!虽然这段代码可以解决问题,including an explanation 解决问题的方式和原因确实有助于提高帖子的质量,并可能导致更多的赞成票。请记住,您正在为将来的读者回答问题,而不仅仅是现在提问的人。请edit您的回答添加解释并说明适用的限制和假设。 这很有趣,只需复制粘贴另一个答案并更改一些格式即可。【参考方案3】:

我通过删除所有记录的程序解决了这个问题。使用这种技术截断失败,但删除它对我的意图和目的来说很好。

create or replace  procedure sp_truncate_dwh() as $$

DECLARE 
    tables RECORD;

BEGIN

FOR tables in   SELECT tablename 
                FROM pg_tables 
                WHERE  schemaname = 'dwh'  
                order by tablename
        LOOP
        EXECUTE 'delete from dwh.' || quote_ident(tables.tablename) ;
        END LOOP;
RETURN;

END;
$$ LANGUAGE plpgsql;

--call sp_truncate_dwh()

【讨论】:

Redshift 中的程序自 2019 年 5 月 17 日起才可用 aws.amazon.com/about-aws/whats-new/2019/05/… 所以这可能是一个有趣的使用程序的解决方案,我会试一试【参考方案4】:

除了 demircioglu 的回答之外,我必须在每个 drop 语句之后添加 Commit 以删除我的架构中的所有表。 SELECT 'DROP TABLE IF EXISTS ' || tablename || ' CASCADE; COMMIT;' FROM pg_tables WHERE schemaname = '&lt;your_schema&gt;' P.S.:我不需要声誉才能将此注释添加为评论,而必须添加为答案。

【讨论】:

【参考方案5】:

在我的 PC 上本地使用 Python 和 pyscopg2 我想出了这个脚本来删除 schema 中的所有表:

import psycopg2


schema = "schema_to_be_deleted"
try:
    conn = psycopg2.connect("dbname='' port='' host='' user='' password=''".format("DB_NAME", "DB_PORT", "DB_HOST", "DB_USER", "DB_PWD"))
    cursor = conn.cursor()

    cursor.execute("SELECT tablename FROM pg_tables WHERE schemaname = '%s'" % schema)
    rows = cursor.fetchall()
    for row in rows:
        cursor.execute("DROP TABLE .".format(schema, row[0]))

    cursor.close()
    conn.commit()

except psycopg2.DatabaseError as error:
    logger.error(error)
finally:
    if conn is not None:
        conn.close()

正确替换 DB_NAMEDB_PORTDB_HOSTDB_USERDB_PWD 的值以连接到 Redshift DB

【讨论】:

如何导入库? 如果您指的是psycopg2,我认为如果您使用 pip 作为数据包管理器pypi.org/project/psycopg2,那么简单的pip install psycopg2 应该可以完成这项工作@ 不应该在 AWS 中导入那个库吗?要在 AWS 中使用? @Henrov 我将这个 Python 脚本作为客户端执行到我的本地 PC 中,并通过凭据连接到 Redshift 集群,就像任何其他 DBMS 一样【参考方案6】:

以下方法与其他答案的不同之处在于它为我们要删除的所有表生成一个 SQL 语句。

SELECT
    'DROP TABLE ' ||
    LISTAGG("table", ', ') ||
    ';'
FROM
    svv_table_info
WHERE
    "table" LIKE 'staging_%';

示例结果:

DROP TABLE staging_077815128468462e9de8ca6fec22f284, staging_abc, staging_123;

与其他答案一样,您需要复制生成的 SQL 并单独执行。

参考文献

|| 运算符连接字符串 LISTAGG 函数将每个表名连接成一个带分隔符的字符串 使用表svv_table_info 是因为LISTAGG 不想为我使用pg_tables。投诉:

必须在至少一个用户创建的表上应用一个或多个使用的函数。仅用户表函数的示例有 LISTAGG、MEDIAN、PERCENTILE_CONT 等

UPD。我刚刚注意到SVV_TABLE_INFO 页面显示:

SVV_TABLE_INFO 视图不返回空表的任何信息。

...这意味着空表将不在此查询返回的列表中。我通常会删除临时表以节省磁盘空间,所以这并没有给我带来太多困扰;但总的来说应该考虑这个因素。

【讨论】:

以上是关于删除 Redshift 架构中的所有表 - 不删除权限的主要内容,如果未能解决你的问题,请参考以下文章

RedShift:删除语句不允许表别名?

删除由 Amazon Redshift 创建的临时表

从 redshift 中删除外部表的所有分区

删除 Redshift 中的循环

删除从当前时间起 2 个月前最近访问的 Redshift 表

仅当表存在时如何删除 Amazon Redshift 中的表