Cómo eliminar varias tablas en PostgreSQL usando un comodín

83

Cuando se trabaja con particiones, a menudo es necesario eliminar todas las particiones a la vez.

sin embargo

DROP TABLE tablename*

No funciona. (No se respeta el comodín).

¿Existe una forma elegante (léase: fácil de recordar) de colocar varias tablas en un comando con un comodín?

Tom Feiner
fuente

Respuestas:

116

Utilice una lista separada por comas:

DROP TABLE foo, bar, baz;

Si realmente necesitas un revólver, este hará su trabajo:

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');
Frank Heikens
fuente
3
¡Gracias por responder! Una lista separada por comas es ideal para eliminar una pequeña lista de tablas. Sin embargo, no es práctico eliminar 20 mesas a la vez (o más). Reorientaré la pregunta para que sea más clara.
Tom Feiner
2
Lo siento, esta es la única opción que tienes. Podría construir una función almacenada para esto, pero es muy probable que se
pegue un
4
Función agregada, ¡diviértete! Y tenga cuidado, este podría destruir toda su base de datos.
Frank Heikens
solo falta un || ' CASCADE ';y es perfecto
MFARID
28

Aquí hay otra respuesta hackear a este problema. Funciona en ubuntuy quizás en otros sistemas operativos también. hacer un \dtsímbolo del sistema en postgres (el símbolo del sistema se estaba ejecutando dentro genome-terminalen mi caso). Entonces verá muchas tablas en la terminal. Ahora use la ctrl+click-dragfuncionalidad de genome-terminalpara copiar todos los nombres de las tablas. ingrese la descripción de la imagen aquíAbra Python, realice un procesamiento de cadenas (reemplace '' por '' y luego '\ n' por ',') y obtendrá una lista separada por comas de todas las tablas. Ahora en psql shell haz un drop table CTRL+SHIFT+Vy listo. Sé que es demasiado específico, solo quería compartirlo. :)

puntas
fuente
Esto funciona muy bien, le permite ser fácilmente explícito sobre lo que quiere hacer.
Brad Koch
5
Lo que hago es similar, escribo: DROP TABLE whatever_y luego presiono TAB, copie todas las tablas al portapapeles, abra sublime, busque / reemplace y reemplace usando expresiones regulares, \s+para ,y pegue en la terminal.
Alfonso Pérez
sí, esto es para 5 o muchas mesas. para una lista larga, ejecute una consulta de nombres de tablas, saque de psql a su editor usando \e, copie en su lista y coloque comas.
Merlin
Además, en pgadmin3, si selecciona el nombre del esquema y luego va a la pestaña 'Dependientes', puede seleccionar todas las tablas (usando la tecla de mayúsculas) y luego copiarlas todas usando CTRL + C. Luego use algún editor de texto para formar una TABLA DROP [ nombre, ..] consulta.
Mate Šimović
18

Usé esto.

echo "select 'drop table '||tablename||';' from pg_tables where tablename like 'name%'" | \
    psql -U postgres -d dbname -t | \
    psql -U postgres -d dbname

Sustituya los valores apropiados por dbnamey name%.

isaaclw
fuente
13

Siempre me he sentido mucho más cómodo creando un script sql que pueda revisar y probar antes de ejecutarlo que confiar en obtener el plpgsql correcto para que no destruya mi base de datos. Algo simple en bash que selecciona los nombres de las tablas del catálogo y luego crea las declaraciones de caída para mí. Entonces, para 8.4.x obtendría esta consulta básica:

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

A la que puede agregar una cláusula where. ( where c.relname ilike 'bubba%')

La salida se ve así:

         Name          
-----------------------
 drop table public.a1;
 drop table public.a2;

Entonces, guárdelo en un archivo .sql y ejecútelo con psql -f filename.sql

Scott Marlowe
fuente
Como seguimiento, si coloca todas las tablas que necesitan eliminarse en el mismo esquema, puede eliminarlas con cascade: drop schema abc cascade;
Scott Marlowe
Tenga en cuenta que esta consulta también producirá un drop tablecomando para cualquier secuencia que encuentre ( relkind = 'S'). drop tableen una secuencia fallará. En su lugar, elimine 'S'de la relkind INcláusula. Si necesita eliminar secuencias, select 'drop sequence'c.relkind = 'S'
cree
9

Divulgación: esta respuesta está destinada a usuarios de Linux.

Agregaría algunas instrucciones más específicas a lo que dijo @prongs:

  • \dtpuede admitir comodines: por lo que puede ejecutar, \dt myPrefix*por ejemplo, para seleccionar solo las tablas que desea eliminar;
  • después CTRL-SHIFT-DRAGpara seleccionar y luego CTRL-SHIFT-Ccopiar el texto;
  • adentro vim, vaya INSERT MODEay pegue las tablas con CTRL-SHIFT-V;
  • presione ESC, luego ejecute :%s/[ ]*\n/, /gpara traducirlo a una lista separada por comas, luego puede pegarlo (excluyendo la última coma) en DROP TABLE % CASCADE.
Campa
fuente
3

Usando herramientas de línea de comandos de Linux, se puede hacer de esta manera:

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 {};"

NOTA: El último eco está ahí porque no pude encontrar una manera de poner comillas alrededor del comando de soltar, por lo que debe copiar y pegar la salida y agregar las comillas usted mismo.

Si alguien puede solucionar ese problema menor, sería una salsa increíble.

Jon
fuente
1

Entonces enfrenté este problema hoy. Cargué mi servidor db a través de pgadmin3 y lo hice de esa manera. Las tablas están ordenadas alfabéticamente, por lo que cambiar y hacer clic seguido de eliminar funciona bien.

Ben
fuente
Puede hacer esto, pero debe usar la ventana 'Propiedades'
Matt