I regularly need to delete all the data from my PostgreSQL database before a rebuild. How would I do this directly in SQL?
At the moment I've managed to come up with a SQL statement that returns all the commands I need to execute:
SELECT 'TRUNCATE TABLE ' || tablename || ';' FROM pg_tables WHERE tableowner='MYUSER';
But I can't see a way to execute them programmatically once I have them.
FrustratedWithFormsDesigner is correct, PL/pgSQL can do this. Here's the script:
This creates a stored function (you need to do this just once) which you can afterwards use like this:
Could you use dynamic SQL to execute each statement in turn? You would probably have to write a PL/pgSQL script to do this.
http://www.postgresql.org/docs/8.3/static/plpgsql-statements.html (section 38.5.4. Executing Dynamic Commands)
If I have to do this, I will simply create a schema sql of current db, then drop & create db, then load db with schema sql.
Below are the steps involved:
1) Create Schema dump of database (
--schema-only
)pg_dump mydb -s > schema.sql
2) Drop database
drop database mydb;
3) Create Database
create database mydb;
4) Import Schema
psql mydb < schema.sql
Cleaning
AUTO_INCREMENT
version:Explicit cursors are rarely needed in plpgsql. Just use the simpler and faster implicit cursor of a
FOR
loop:Note: Since table names are not unique per database, you have to schema-qualify table names to be sure. Also, I limit the function to the default schema 'public'. Adapt to your needs, but be sure to exclude the system schemas
pg_*
andinformation_schema
.Be very careful with these functions. They nuke your database. I added a child safety device. Comment the
RAISE NOTICE
line and uncommentEXECUTE
to prime the bomb ...format()
requires Postgres 9.1 or later. In older versions concatenate the query string like this:Single command, no loop
Since we can
TRUNCATE
multiple tables at once we don't need any cursor or loop at all:Aggregate all table names and execute a single statement. Simpler, faster:
Call:
Refined query
You don't even need a function. In Postgres 9.0+ you can execute dynamic commands in a
DO
statement. And in Postgres 9.5+ the syntax can be even simpler:About the difference between
pg_class
,pg_tables
andinformation_schema.tables
:About
regclass
and quoted table names:For repeated use
It might be simpler and (much) faster to create a "template" database (let's name it
my_template
) with your vanilla structure and all empty tables. Then go through aDROP
/CREATE DATABASE
cycle:This is extremely fast, because Postgres copies the whole structure on the file level. No concurrency issues or other overhead slowing you down.
In this case it would probably be better to just have an empty database that you use as a template and when you need to refresh, drop the existing database and create a new one from the template.