Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

How can I delete all tables in postgresql, working from the command line?

I don't want to drop the database itself - just all tables and all the data in them.

Thanks.

share|improve this question
What command line are you talking about? For all we know you're looking for a Windows PowerShell implementation. – Greg Smith Jul 25 '10 at 1:24
Sorry. Working on Unix, after typing 'psql' at the command line - so the psql command-line environment itself. – AP257 Jul 25 '10 at 8:34
7  
DROP SCHEMA public CASCADE; -- shudder – wildplasser Jun 4 '12 at 20:18
4  
Why'd you say "shudder"? – Joe Van Dyk Oct 28 '12 at 1:19

8 Answers

You can use the string_agg function to make a comma-separated list, perfect for DROP TABLE. From a bash script:

#!/bin/bash
TABLES=`psql $PGDB -t --command "SELECT string_agg(table_name, ',') FROM information_schema.tables WHERE table_schema='public'"`

echo Dropping tables:${TABLES}
psql $PGDB --command "DROP TABLE IF EXISTS ${TABLES} CASCADE"
share|improve this answer

If all of your tables are in a single schema, this approach could work (below code assumes that the name of your schema is 'public')

drop schema public cascade;
create schema public;
share|improve this answer
4  
+1 for create schema public; – manish_s Dec 14 '12 at 8:48
1  
Note that this will also delete all functions, views, etc defined in the public schema. – Brad Koch Mar 24 at 0:15

You can write a query to generate a SQL script like this:

select 'drop table "' || tablename || '" cascade;' from pg_tables;

Or:

select 'drop table if exists "' || tablename || '" cascade;' from pg_tables;

In case some tables are automatically dropped due to cascade option in a previous sentence.

Additionally, as stated in the comments, you might want to filter the tables you want to drop by schema name:

select 'drop table if exists "' || tablename || '" cascade;' 
  from pg_tables
 where schemaname = 'public'; -- or any other schema

And then run it.

Glorious COPY+PASTE will also work.

share|improve this answer
1  
I think you meant: You can write a query like this... ...And then run the output of the query – Vinko Vrsalovic Jul 24 '10 at 23:31
2  
True. That's what I meant. :-) – Pablo Santa Cruz Jul 24 '10 at 23:31
4  
select 'drop table if exists "' || tablename || '" cascade;' from pg_tables; will make sure tables with uppercase are also properly dropped. – Ivo van der Wijk Apr 19 '12 at 14:03
1  
the clause "where schemaname = 'public'" that LenW added in his answer can be very useful to reduce the scope of deletion to only the database you managed and not the system's ones – Guillaume Gendre Oct 29 '12 at 16:36
1  
Love it! This is a great bit of stuff. – Nicholas DiPiazza Jan 26 at 0:40
drop schema public cascade;

should do the trick.

share|improve this answer
1  
this absolutely works! – Luca Trazzi Jan 9 at 18:44
3  
Note that this will also delete all functions, views, etc defined in the public schema. – Joe Van Dyk Jan 9 at 22:23

Just in case... Simple Python script that clean Postgresql database

import psycopg2
import sys

# Drop all tables from a given database

try:
    conn = psycopg2.connect("dbname='akcja_miasto' user='postgres' password='postgres'")
    conn.set_isolation_level(0)
except:
    print "Unable to connect to the database."

cur = conn.cursor()

try:
    cur.execute("SELECT table_schema,table_name FROM information_schema.tables WHERE table_schema = 'public' ORDER BY table_schema,table_name")
    rows = cur.fetchall()
    for row in rows:
        print "dropping table: ", row[1]   
        cur.execute("drop table " + row[1] + " cascade") 
    cur.close()
    conn.close()        
except:
    print "Error: ", sys.exc_info()[1]

Make sure that after copying it the indentation is right since Python relies on it.

share|improve this answer

Following Pablo and LenW, here's a one-liner that does it all both preparing and then executing:

psql -U $PGUSER $PGDB -t -c "select 'drop table \"' || tablename || '\" cascade;' from pg_tables where schemaname = 'public'" | psql -U $PGUSER $PGDB

NB: either set or replace $PGUSER and $PGDB with the values you want

share|improve this answer
works great, thanks for the tip ! – Guillaume Gendre Oct 30 '12 at 9:33

If you have the PL/PGSQL procedural language installed you can use the following to remove everything without a shell/Perl external script.

DROP FUNCTION IF EXISTS remove_all();

CREATE FUNCTION remove_all() RETURNS void AS $$
DECLARE
    rec RECORD;
    cmd text;
BEGIN
    cmd := '';

    FOR rec IN SELECT
            'DROP SEQUENCE ' || quote_ident(n.nspname) || '.'
                || quote_ident(c.relname) || ' CASCADE;' AS name
        FROM
            pg_catalog.pg_class AS c
        LEFT JOIN
            pg_catalog.pg_namespace AS n
        ON
            n.oid = c.relnamespace
        WHERE
            relkind = 'S' AND
            n.nspname NOT IN ('pg_catalog', 'pg_toast') AND
            pg_catalog.pg_table_is_visible(c.oid)
    LOOP
        cmd := cmd || rec.name;
    END LOOP;

    FOR rec IN SELECT
            'DROP TABLE ' || quote_ident(n.nspname) || '.'
                || quote_ident(c.relname) || ' CASCADE;' AS name
        FROM
            pg_catalog.pg_class AS c
        LEFT JOIN
            pg_catalog.pg_namespace AS n
        ON
            n.oid = c.relnamespace WHERE relkind = 'r' AND
            n.nspname NOT IN ('pg_catalog', 'pg_toast') AND
            pg_catalog.pg_table_is_visible(c.oid)
    LOOP
        cmd := cmd || rec.name;
    END LOOP;

    FOR rec IN SELECT
            'DROP FUNCTION ' || quote_ident(ns.nspname) || '.'
                || quote_ident(proname) || '(' || oidvectortypes(proargtypes)
                || ');' AS name
        FROM
            pg_proc
        INNER JOIN
            pg_namespace ns
        ON
            (pg_proc.pronamespace = ns.oid)
        WHERE
            ns.nspname =
            'public'
        ORDER BY
            proname
    LOOP
        cmd := cmd || rec.name;
    END LOOP;

    EXECUTE cmd;
    RETURN;
END;
$$ LANGUAGE plpgsql;

SELECT remove_all();

Rather than type this in at the "psql" prompt I would suggest you copy it to a file and then pass the file as input to psql using the "--file" or "-f" options:

psql -f clean_all_pg.sql

Credit where credit is due: I wrote the function, but think the queries (or the first one at least) came from someone on one of the pgsql mailing lists years ago. Don't remember exactly when or which one.

share|improve this answer

As per Pablo above, to just drop from a specific schema, with respect to case:

select 'drop table "' || tablename || '" cascade;' 
from pg_tables where schemaname = 'public';
share|improve this answer
thanks for the "where schemaname = 'public'" tip. useful. – Guillaume Gendre Oct 29 '12 at 16:37

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.