使用分区时,通常需要一次删除所有分区。
然而
DROP TABLE tablename*
不起作用。 (不遵守通配符)。
使用通配符在一个命令中删除多个表是否有优雅(读取:易记)的方式?
答案 0 :(得分:100)
使用逗号分隔列表:
DROP TABLE foo, bar, baz;
如果你真的需要一个步枪,这个就可以完成它的工作:
CREATE OR REPLACE FUNCTION footgun(IN _schema TEXT, IN _parttionbase TEXT)
RETURNS void
LANGUAGE plpgsql
AS
$$
DECLARE
row record;
BEGIN
FOR row IN
SELECT
table_schema,
table_name
FROM
information_schema.tables
WHERE
table_type = 'BASE TABLE'
AND
table_schema = _schema
AND
table_name ILIKE (_parttionbase || '%')
LOOP
EXECUTE 'DROP TABLE ' || quote_ident(row.table_schema) || '.' || quote_ident(row.table_name);
RAISE INFO 'Dropped table: %', quote_ident(row.table_schema) || '.' || quote_ident(row.table_name);
END LOOP;
END;
$$;
SELECT footgun('public', 'tablename');
答案 1 :(得分:25)
这是另一个解决这个问题的黑客问题。它适用于ubuntu
,也许还有其他一些操作系统。在postgres命令提示符下执行\dt
(在我的情况下,命令提示符在genome-terminal
内运行)。然后你会在终端看到很多桌子。现在使用ctrl+click-drag
的{{1}}功能复制所有表格'名。 打开python,进行一些字符串处理(替换''''然后' \ n' by',&# 39;)然后你得到所有表的逗号分隔列表。现在在psql shell中执行genome-terminal
并完成。我知道它太具体了,我只想分享。 :)
答案 2 :(得分:12)
我用过这个。
echo "select 'drop table '||tablename||';' from pg_tables where tablename like 'name%'" | \
psql -U postgres -d dbname -t | \
psql -U postgres -d dbname
答案 3 :(得分:8)
我一直觉得创建一个sql脚本更舒服我可以在运行它之前查看和测试,而不是依赖于正确地获取plpgsql所以它不会吹走我的数据库。在bash中简单的选择目录中的表名,然后为我创建drop语句。因此,对于8.4.x,您将获得此基本查询:
SELECT 'drop table '||n.nspname ||'.'|| c.relname||';' as "Name"
FROM pg_catalog.pg_class c
LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE c.relkind IN ('r','v','S','')
AND n.nspname <> 'pg_catalog'
AND n.nspname <> 'information_schema'
AND n.nspname !~ '^pg_toast'
AND pg_catalog.pg_table_is_visible(c.oid);
您可以在其中添加where子句。 (其中c.relname ilike'bubba%')
输出如下:
Name
-----------------------
drop table public.a1;
drop table public.a2;
因此,将其保存到.sql文件并使用psql -f filename.sql
运行它答案 4 :(得分:7)
披露:此答案适用于Linux用户。
我会在@prongs所说的内容中添加一些更具体的说明:
\dt
可以支持通配符:因此您可以运行\dt myPrefix*
,例如,只选择要删除的表格; CTRL-SHIFT-DRAG
之后选择CTRL-SHIFT-C
来复制文字; vim
中INSERT MODE
并粘贴表格CTRL-SHIFT-V
; ESC
,然后运行:%s/[ ]*\n/, /g
将其翻译为以逗号分隔的列表,然后您可以在DROP TABLE % CASCADE
中粘贴它(不包括最后一个逗号)。答案 5 :(得分:2)
使用linux命令行工具,可以这样做:
psql -d mydb -P tuples_only=1 -c '\dt' | cut -d '|' -f 2 | paste -sd "," | sed 's/ //g' | xargs -I{} echo psql -d mydb -c "drop table {};"
注意:最后一个回显是因为我找不到在drop命令周围放置引号的方法,所以你需要复制并粘贴输出并自己添加引号。
如果有人能解决那个小问题,那就太棒了。
答案 6 :(得分:1)
所以今天我遇到了这个问题。我通过pgadmin3加载了我的服务器数据库并按照这种方式执行。表格按字母顺序排序,因此移位和点击后删除效果很好。
答案 7 :(得分:1)
我喜欢 the answer 中的 @Frank Heikens。感谢那。不管怎样,我想改进一下;
让我们假设我们的分区表名称是 {{
"config_changes": [
{
"new_val": {
"db": "dbName",
"durability": "hard",
"id": "0f72a570-7998-49f7-affc-96cbdd1ea086",
"indexes": [],
"name": "tableName",
"primary_key": "id",
"shards": [
{
"nonvoting_replicas": [],
"primary_replica": "replicasssss_iu1",
"replicas": [
"replicasssss_iu1"
]
}
],
"write_acks": "majority"
},
"old_val": null
}
],
"tables_created": 1
}}
并且我们有一个数字后缀,我们每次都会增加它。像partitioned_table
、partitioned_table_00
... partitioned_table_01
partitioned_table_99
为了执行,你可以运行下面的代码;
CREATE OR REPLACE drop_old_partitioned_tables(schema_name TEXT, partitioned_table_name TEXT, suffix TEXT)
RETURNS TEXT
LANGUAGE plpgsql
AS
$$
DECLARE
drop_query text;
BEGIN
SELECT 'DROP TABLE IF EXISTS ' || string_agg(format('%I.%I', table_schema, table_name), ', ')
INTO drop_query
FROM information_schema.tables
WHERE table_type = 'BASE TABLE'
AND table_schema = schema_name
AND table_name <= CONCAT(partitioned_table_name, '_', suffix) -- It will also drop the table which equals the given suffix
AND table_name ~ CONCAT(partitioned_table_name, '_\d{2}');
IF drop_query IS NULL THEN
RETURN 'There is no table to drop!';
ELSE
EXECUTE drop_query;
RETURN CONCAT('Executed query: ', (drop_query));
END IF;
END;
$$;
顺便提一下,如果你想为每一年划分你的表,你的表后缀应该是像 SELECT drop_old_partitioned_tables('public', 'partitioned_table', '10')
这样的年份。即使您的数据较大,无法按年进行分区,您也可以像 partitioned_table_2021
一样按月进行分区。不要忘记根据您的需要调整您的代码。
答案 8 :(得分:0)
感谢 Jon 回答的另一个解决方案:
tables=`psql -d DBNAME -P tuples_only=1 -c '\dt' |awk -F" " '/table_pattern/ {print $3","}'`
psql -d DBNAME -c "DROP TABLE ${tables%?};";