110 votes

Comment supprimer plusieurs tables dans PostgreSQL à l'aide d'un caractère de remplacement ?

Lorsque l'on travaille avec des partitions, il est souvent nécessaire de supprimer toutes les partitions en même temps.

Cependant

DROP TABLE tablename*

Ne fonctionne pas. (Le caractère générique n'est pas respecté).

Existe-t-il un moyen élégant (lire : facile à retenir) de déposer plusieurs tables en une seule commande avec un caractère générique ?

156voto

Frank Heikens Points 29270

Utilisez une liste séparée par des virgules :

DROP TABLE foo, bar, baz;

Si vous avez vraiment besoin d'un pistolet à pied, celui-ci fera son travail :

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) || ' CASCADE ';
        RAISE INFO 'Dropped table: %', quote_ident(row.table_schema) || '.' || quote_ident(row.table_name);
    END LOOP;
END;
$$;

SELECT footgun('public', 'tablename');

3 votes

Merci de votre réponse ! Une liste séparée par des virgules est idéale pour supprimer une petite liste de tableaux. Cependant, elle n'est pas pratique pour déposer 20 tableaux à la fois (ou plus). Je vais recentrer la question pour être plus clair.

2 votes

Désolé, c'est la seule option que vous avez. Vous pourriez construire une fonction stockée pour cela, mais il y a de fortes chances pour que vous vous tiriez une balle dans le pied : en laissant tomber trop de tables...

6 votes

Fonction ajoutée, amusez-vous ! Et faites attention, celle-ci pourrait détruire toute votre base de données.

33voto

prongs Points 2209

Voici une autre réponse pirate à ce problème. Elle fonctionne dans ubuntu et peut-être d'autres os aussi. \dt dans l'invite de commande postgres (l'invite de commande était exécutée à l'intérieur de l'ordinateur de l'entreprise). genome-terminal dans mon cas). Vous verrez alors beaucoup de tableaux dans le terminal. Maintenant, utilisez ctrl+click-drag la fonctionnalité de la genome-terminal pour copier les noms de toutes les tables. enter image description here Ouvrez python, faites un peu de traitement des chaînes de caractères (remplacez ' ' par '' et puis ' \n par ',') et vous obtenez une liste de toutes les tables séparées par des virgules. Maintenant, dans le shell psql, faites un drop table CTRL+SHIFT+V et vous avez terminé. Je sais que c'est trop spécifique, je voulais juste partager. :)

0 votes

Cela fonctionne très bien, cela vous permet d'être facilement explicite sur ce que vous voulez faire.

6 votes

Ce que je fais est similaire, j'écris : DROP TABLE whatever_ puis appuyez sur TAB, copiez tous les tableaux dans le presse-papiers, ouvrez sublime, recherchez/remplacez, et remplacez en utilisant des expressions régulières, \s+ pour , et coller sur le terminal.

0 votes

Oui c'est ça pour 5 à plusieurs tables. pour une longue liste, lancez une requête pour les noms de tables, puis envoyez-la de psql à votre éditeur en utilisant \e copiez votre liste et placez les virgules.

17voto

Scott Marlowe Points 2231

Je me suis toujours senti plus à l'aise en créant un script sql que je peux revoir et tester avant de l'exécuter, plutôt que de compter sur le plpgsql pour qu'il ne fasse pas exploser ma base de données. Quelque chose de simple en bash qui sélectionne les noms d'onglet à partir du catalogue, puis crée les déclarations de dépôt pour moi. Ainsi, pour 8.4.x, vous obtiendrez cette requête de base :

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

À laquelle vous pouvez ajouter une clause where. ( where c.relname ilike 'bubba%' )

La sortie ressemble à ceci :

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

Donc, sauvegardez-le dans un fichier .sql et exécutez-le avec psql -f nomfichier.sql.

0 votes

Si vous placez toutes les tables qui doivent être supprimées dans le même schéma, vous pouvez le supprimer en cascade : drop schema abc cascade ;

0 votes

Notez que cette requête produira également un drop table pour toutes les séquences qu'elle trouve ( relkind = 'S' ). drop table sur une séquence échouera. Au lieu de cela, supprimez 'S' de la relkind IN clause. Si vous avez besoin de supprimer des séquences, construisez une requête similaire avec des données constantes select 'drop sequence' , cette fois avec c.relkind = 'S'

10voto

Campa Points 325

Divulgation : cette réponse est destinée aux utilisateurs de Linux.

J'ajouterais des instructions plus spécifiques à ce que @prongs a dit :

  • \dt peut prendre en charge les caractères génériques : vous pouvez donc exécuter \dt myPrefix* par exemple, pour ne sélectionner que les tables que vous souhaitez supprimer ;
  • après CTRL-SHIFT-DRAG pour sélectionner puis CTRL-SHIFT-C pour copier le texte ;
  • sur vim Allez sur INSERT MODE et coller les tableaux avec CTRL-SHIFT-V ;
  • presse ESC puis exécutez :%s/[ ]*\n/, /g pour le traduire en liste séparée par des virgules, puis vous pouvez le coller (en excluant la dernière virgule) dans le fichier DROP TABLE % CASCADE .

5voto

Jon Points 336

En utilisant les outils de ligne de commande linux, cela peut être fait de cette façon :

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

NOTE : Le dernier écho est là parce que je n'ai pas trouvé le moyen de mettre des guillemets autour de la commande drop, donc vous devez copier et coller la sortie et ajouter les guillemets vous-même.

Si quelqu'un peut résoudre ce problème mineur, ce serait une sauce géniale.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X