4

I want to remove all content from a database without dropping and re-creating the database.

I figured out that dropping all schemas, re-creating 'public' and dropping all temporary tables is a good start. Am I getting rid of all content compared to a "virgin" database or missing something?

const systemSchemas = ['pg_toast', 'pg_temp_1', 'pg_toast_temp_1', 'pg_catalog', 'information_schema']

return Database.connect(connectionString, db => {

  // DROP schemas except systemSchemas
  const schemas = await db.queryRows(`SELECT nspname AS name FROM pg_catalog.pg_namespace ORDER BY nspname`).map(row => row.name).filter(name => {
    return systemSchemas.includes(name) === false
  })
  await Promise.resolve(schemas).each(name => db.query(`DROP SCHEMA "${name}" CASCADE`))

  // DROP temporary tables
  const sql = `SELECT c.relname AS name FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace WHERE n.nspname like 'pg_temp_%' AND pg_catalog.pg_table_is_visible(c.oid) AND c.relpersistence = 't'`
  return db.queryRows(sql).each(row => db.query(`DROP TABLE IF EXISTS "${row.name}"`))

  // CREATE public schema
  return db.query(`CREATE SCHEMA public`)
  .then(() => db.query(`GRANT ALL ON SCHEMA public TO postgres`))
  .then(() => db.query(`GRANT ALL ON SCHEMA public TO public`))
})

1 Answer 1

4

You cannot exclude just pg_temp_1 and pg_toast_temp_1 because there may be more temporary schemas. It seems that it is sufficient to drop all non-system schemas including temporary ones, so you should exclude only pg_catalog, information_schema and pg_toast and not try to drop temporary tables.

Note that you can do this in a single DO Postgres command:

do $$
declare
    schema_name text;
begin
    for schema_name in
        select nspname
        from pg_catalog.pg_namespace 
        where nspname not in ('pg_catalog', 'information_schema', 'pg_toast')
    loop
        execute format('drop schema %s cascade', schema_name);
    end loop;
    create schema public;
    grant all on schema public to postgres;
    grant all on schema public to public;
    comment on schema public is 'standard public schema';
end;
$$;
Sign up to request clarification or add additional context in comments.

1 Comment

Great! Thank you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.