How does one drop a template database from PostgreSQL? - postgresql

postgres=# DROP DATABASE template_postgis;
ERROR: cannot drop a template database
http://www.postgresql.org/docs/9.1/static/manage-ag-templatedbs.html makes it seem like if I set template_postgis.datistemplate = false, I'll be able to drop it, but I don't know how to set that.

postgres=# UPDATE pg_database SET datistemplate='false' WHERE datname='template_postgis';
UPDATE 1
postgres=# DROP DATABASE template_postgis;
DROP DATABASE
postgres=#

You can use the alter database command. Much simpler and safer than upsetting metadata.
postgres=# create database tempDB is_template true;
CREATE DATABASE
postgres=# drop database tempDB;
ERROR: cannot drop a template database
postgres=# alter database tempDB is_template false;
ALTER DATABASE
postgres=# drop database tempDB;
DROP DATABASE
postgres=#
Documentation

update pg_database set datistemplate=false where datname='template0';
update pg_database set datistemplate=false where datname='template1';
....
Creating script to analyze new cluster ok
Creating script to delete old cluster ok
Checking for hash indexes ok
Upgrade Complete
----------------

Related

Setting privileges on foreign table on Postgres

How do foreign table privileges work? A simple example where both source_db and destination_db are Postgres databases.
source_db:
-- create user for user mapping
CREATE USER fdw_user WITH PASSWORD 'secret';
-- create table
CREATE TABLE data (value TEXT);
-- set privileges
GRANT ALL ON TABLE data TO fdw_user;
destination_db:
-- create extension
CREATE EXTENSION postgres_fdw;
-- create server
CREATE SERVER remote_source
FOREIGN DATA WRAPPER postgres_fdw
OPTIONS (host 'source.domain.com', dbname 'source_db');
-- create user mapping
CREATE USER MAPPING
FOR PUBLIC
SERVER remote_source
OPTIONS (user 'fdw_user', password 'secret');
-- create foreign table
CREATE FOREIGN TABLE data_from_source(value TEXT)
SERVER remote_source
OPTIONS (table_name 'data');
Now setting privileges for any user in destination_db seems to have no effect, like
GRANT SELECT ON TABLE data_from_source TO localuser;
How can I set privileges on foreign table?
The problem was PgAdmin III. ACL of foreign table changed but PgAdmin did not show it. Psql on command line \dp+ data_from_source shows the ACL as expected.

PostgreSQL 9.6 - can't connect to database created from a custom template database

I have created a database foo which I am using as a template database to create other databases from.
I am running all PostgreSQL in a Docker container (not sure if that is relevant to the problem at hand).
Here is the (truncated) SQL
CREATE DATABASE foo WITH ENCODING 'UTF8' template0;
\i db_schema_foo.sql
-- Create extensions
-- Initialise db with data etc ...
CREATE DATABASE foobar TEMPLATE foo;
(Truncated) console output:
CREATE DATABASE
You are now connected to database "foo" as user "postgres".
CREATE TABLE
CREATE INDEX
CREATE TABLE
CREATE INDEX
CREATE TABLE
...
CREATE INDEX
CREATE TABLE
CREATE INDEX
CREATE TABLE
CREATE TABLE
CREATE TABLE
CREATE TABLE
CREATE TABLE
CREATE TABLE
CREATE INDEX
CREATE TABLE
CREATE INDEX
CREATE TABLE
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE DATABASE
FATAL: database "foobar" does not exist
psql:/docker-entrypoint-initdb.d/create_databases.sql:82: \connect: FATAL: database "foobar" does not exist
From the console, I'm assuming that both foo and foobar are created - so why can't I connect to database foobar?
Use the psql command \l to see which databases exist.
I would expect database foobar to not exist.
That would mean that the CREATE DATABASE statement has failed.
Can you get the error message for that?
My suspicion is that creating the database failed because you were still connected to the template database foo. You can only use a database with no active connections as template.
CREATE DATABASE in output means either that databse was successfully created, if there would be error and no warning, like here:
t=# set client_min_messages TO fatal;
SET
t=# create database t;
t=# set client_min_messages TO warning;
SET
t=# create database t;
ERROR: database "t" already exists
there would not be such output - CREATE DATABASE
so next line FATAL: database "foobar" does not exist (together with knowledge database was created) leads to idea that OP is connecting to different cluser, or different database
In private chat we found that database created was "Foobar" and database attempting to connect was Foobar and thus "foobar", which does not exist indeed, as "Foobar" does

pg_restore --clean is not dropping and clearing the database

I am having an issue with pg_restore --clean not clearing the database.
Or do I misunderstand what the --clean does, I am expecting it to truncate the database tables and reinitialize the indexes/primary keys.
I am using 9.5 on rds
This is the full command we use
pg_restore --verbose --clean --no-acl --no-owner -h localhost -U superuser -d mydatabase backup.dump
Basically what is happening is this.
I do a nightly backup of my production db, and restore it to an analytics db for the analyst to churn and run their reports.
I found out recently that the rails application used to view the reports was complaining that the primary keys were missing from the restored analytics database.
So I started investigating the production db, the analytics db etc. Which was when I realized that multiple rows with the same primary key existed in the analytics database.
I ran a few short experiments and realized that every time the pg_restore script is run it inserts duplicate data into the tables, this leads me to think that the --clean is not dropping and restoring the data. Because if I were to drop the schema beforehand, I don't get duplicate data.
To remove all tables from a database (but keep the database itself), you have two options.
Option 1: Drop the entire schema
You will need to re-create the schema and its permissions. This is usually good enough for development machines only.
DROP SCHEMA public CASCADE;
CREATE SCHEMA public;
GRANT ALL ON SCHEMA public TO postgres;
GRANT ALL ON SCHEMA public TO public;
Applications usually use the "public" schema. You may encounter other schema names when working with a (legacy) application's database.
Note that for Rails applications, dropping and recreating the database itself is usually fine in development. You can use bin/rake db:drop db:create for that.
Option 2: Drop each table individually
Prefer this for production or staging servers. Permissions may be managed by your operations team, and you do not want to be the one who messed up permissions on a shared database cluster.
The following SQL code will find all table names and execute a DROP TABLE statement for each.
DO $$ DECLARE
r RECORD;
BEGIN
FOR r IN (SELECT tablename FROM pg_tables WHERE schemaname = current_schema()) LOOP
EXECUTE 'DROP TABLE IF EXISTS ' || quote_ident(r.tablename) || ' CASCADE'; -- DROP TABLE IF EXISTS instead DROP TABLE - thanks for the clarification Yaroslav Schekin
END LOOP;
END $$;
Original:
https://makandracards.com/makandra/62111-how-to-drop-all-tables-in-postgresql

PostgreSQL 9.3: Alter database to set User

I want to restore the Database in postgreSQL using the function.
In the function, I want to do the following steps:
First I want to alter the Database to the SINGLE_USER to access,
Restore the Database,
Again I want to alter the Database to set the MLTI_USER.
In SQL Server I used the following script:
ALTER DATABASE DBName SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
RESTORE DATABASE DBName FROM DISK = #Fullpath with replace;
ALTER DATABASE DBName SET MULTI_USER;
Note: DBName and FullPath will be the parameters to the function.

PostgreSQL to Oracle - Can i change OWNER in Oracle?

I am trying to edit PostgreSQL schema script and make it executable in Oracle (Oracle Express). In PostgreSQL were under the each CREAT TABLE these commands:
ALTER TABLE table_name OWNER TO user;
For example table_name is appuser and user is projectX.
The table is successfully created, but there is an error: ORA-01735: invalid ALTER TABLE option
I have also created another user in my scheme (projectX), but the error is still there. So I am confused. Does this command ALTER TABLE table_name OWNER TO user; even exists in Oracle database?