删除Redshift模式中的所有表(无删除权限)

时间:2019-03-26 13:58:09

标签: sql amazon-redshift

我想删除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)。

还有其他解决方案吗?

6 个答案:

答案 0 :(得分:2)

SELECT 'DROP TABLE IF EXISTS ' 
       || table_name 
       || ' CASCADE;' 
FROM   information_schema.tables 
WHERE  table_schema = '<your_schema>' 
       AND table_name LIKE '<%condition%>' 

答案 1 :(得分:1)

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

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

答案 2 :(得分:0)

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

import logging
import psycopg2

logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger('redshift_debug')

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:
        logger.info("Dropping table " + row[0] + "...")
        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

答案 3 :(得分:0)

我通过删除所有记录的过程解决了它。使用此技术截断失败,但出于我的意图和目的,将其删除可以很好地工作。

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()

答案 4 :(得分:0)

除了demircioglu的回答外,我还必须在每个drop语句后添加Commit才能删除架构中的所有表。 import sys if __name__ =='__main__': year_name = sys.argv[1] filename = open('year_2011.txt','r').readlines() for line in filename: line=line.strip('\t') # *seperated by tabs* year,y,x, amt # *columns in each of the filenames* y = int(y) x = int(x) amt = float(amt) 附注:我没有信誉要求将此注释添加为注释,也不必添加为答案。

答案 5 :(得分:0)

以下方法与其他答案的不同之处在于,它为我们要删除的所有表生成一条 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 视图不返回空表的任何信息。

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