Cannot drop a schema in PostgreSQL - postgresql

I am trying to drop the schema masterdata from a postgres database, but it does not work. I am using PostgreSQL 9.5. I have 2 databses, one of them has the masterdata schema, which I want to drop. Here is the structure (in DBeaver):
My first attempt was just to execute the SQL statement DROP SCHEMA masterdata in DBeaver, but it tells me, that such a schema does not exist (but it does show it, as we can see in the picture!). Maybe, it does not know, in which of the 2 databses to look for this schema? If so, then how to specify it? I was looking for a way to specify the database, but did not find anything.
However, my second attempt was to use psql and to type the command
psql -U postgres -d bobd -h localhost
So here I concretely specify, which databse to use! psql does not answer anything, it just asks for the next command. And when I type \dn to view the current schemas, then the schema masterdata is still there! Also, the data in the tables is still there. I tried the same with other users instead of the user postgres (also with the owner of the schema to remove), but the result is the same.
Any ideas, what I am doing wrong?

Your DBeaver session was probably connected to the wrong database (postgres?).
Do it from the psql session, that is easiest.
Right after \dn showed you that there is indeed such a schema, enter
DROP SCHEMA masterdata;
It may complain that there are objects in that schema. Then you can use
DROP SCHEMA masterdata CASCADE;

Maybe your schema name contains characters that do not display or display differently (maybe capital letters) in DBeaver. I suggest you check names by running following query:
SELECT '~~' || nspname || '~~' FROM pg_catalog.pg_namespace;
Try adding quotes around schema name if you have added capital letters when creating schema.

Related

Return name of the Postgres database containing value in a row in a table

I am looking for some implementation to essentially search the entire Postgres instance, all of it's databases to find the database containing a specific row in a specific table.
So I have a Postgres instance with 170 databases, every database has the exact same schema and table layout. In each database there is a specific table "SM_Project" and specific row "ProjectName" in said table. We have instances where we know a ProjectName or at least a partial match (can use LIKE with %) but we have no idea which database it lives in.
I am wanting to script, simplify the ability to enter a ProjectName and search the entire Postgres instance (all databases in there) and return the name of the db that contains that record.
I foolishly thought this would be a simple task, with my lack of experience I've tried to do this with several SELECT statements and while I can explicitly connect to a database and search for the record from there, I can't find a way to return the parent database name. I was thinking ti clunkily script it in bash to iterate through the databases until we get a true return on a EXISTS in a SELECT statement. But I feel like I'm overlooking something fundamental.
So my setup is like this"
Postgres
db1
SM_Project
ProjectName
db2
SM_Project
ProjectName
db3
SM_Project
ProjectName
In short I'm looking to return the name of the database that contains a record of ProjectName equal to a string.
Any thoughts would be very welcomed!

pg dump output the schema name and the data

when i use (pg_dump -f backup.sql mydb), the schema name are not included. How to dump that will output also the scheme name(personal). see example below
Output : ALTER TYPE basicinfo OWNER TO postgres;
// note : basicinfo is the name of the table
Expected Output : ALTER TYPE personal.basicinfo OWNER TO postgres;
any ideas?
Global Database properties such as OWNER etc. are always given with SCHEMA names in a pg_dump output.
However, for non-global database objects, as far as I know, there isn't any way to get SCHEMA names prepended to all the database objects. The way the script works is that it sets the SET search_path before-hand all Schema specific database objects... which is more efficient and has the same effect.
In case you are trying to parse an pg_dump output to extract a given SQL line that works independently, you may have to also parse the nearest-preceding SET search_path line and execute that before executing the target line (for e.g. ALTER TYPE) to have the desired effect.
You cant do that using pg_dump directly.
Try to use different tools, They have different implementation for exporting PostgreSQL database.
Here are list of tools:
phpPgAdmin - http://sourceforge.net/projects/phppgadmin
AnySQL Maestro - http://www.sqlmaestro.com/products/anysql/maestro/
DBeaver - http://dbeaver.jkiss.org/
All refence: https://wiki.postgresql.org/wiki/Community_Guide_to_PostgreSQL_GUI_Tools

Group many postgresql databases into separate schemas into same database

We have many postgresql databases with the same structure using only public shcema on each one.
How can I group all of them in a single database using separate schemas?
You can dump the database definition and data out, edit the output by putting the default schema as whatever you choose and run the scripts back into database.
Remember to make the dump in SQL format, pg_dump with default custom format won't work. The schema change will only need a change on a row like
SET search_path TO *whateverschema*
If you don't want to edit the dumps (maybe they're very large), you can of course also restore them one by one to the public schema, alter the tables into the desired schema and then repeat for the next one.
There is no special way to convert an existing database into a schema in another database unfortunately.
I forgot to post the answer afer all klin comment was the answer, this step was the solution,
Inside customer_x database:
alter schema public rename to customer_x;
And then take pg_dump customer_x:
pg_dump "customer_x" --schema "customer_x" -f customer_x.sql
Inside new conglomerated database:
DROP schema customer_x CASCADE;
create schema customer_x;
Then load the dump of customer_x:
psql "conglomerated_database" -f customer_x.sql

Best way to change the owner of a PostgreSQL database and their tables?

I am trying to change the owner of a PostgreSQL database (version > 8.2) and its tables.
I read this solution:
Modify OWNER on all tables simultaneously in PostgreSQL
But is this the best way to do it (for recent versions of PostgreSQL)?. It seems that there is a function REASSIGN OWNED which is better, but this one changes every database owned by the old_role, doesn't it? I only want it for one database.
Like this post:
REASSIGN OWNED BY for 1 specified database
I am not going to change the owner postgres, which is the best way nowadays?
Thank you in advance
According to the manual:
Because REASSIGN OWNED does not affect objects within other databases, it is usually necessary to execute this command in each database
which would seem to meet your requirements, although it also says the command would affect table spaces (which are not specific to the current database).
The second SO answer you linked applies to the special case of the postgres user, which owns the system catalogs. You cannot change the ownership of these.
The two methods that spring to mind for me are:
1) First alter the database name, and then perhaps right a quick script which changes the owner on the current tables to the old tables.
ALTER DATABASE <dbname> OWNER TO <newowner>;
\o altertable.sql
SELECT 'ALTER TABLE ' || table_name || ' OWNER TO <newowner>; ' FROM information_schema WHERE table_schema = <oldowner> and table_catalog = '<dbname>';
\o
\i altertable.sql
The above will generate your commands, then just pop them into a file and execute it.
2) The other option would be to use pg_dump to dump your database in plain text mode and then alter the appropriate strings using search and replace:
pg_dump -Fp -f dbbackup.dmp <dbname>
vi dbbackup.dmp
:%s/oldowner/newowner/g
save and exit
Hope this helps.

restoring database from pg_dump file creates strange tables

I have backup created like this:
pg_dump dbname > file
I am trying to restore the database (after drop database and create database) like this:
psql dbname < file
What I get is a database full of tables that are created with dbname.tablename instead of just tablename.
How do I restore a postgres database making sure the tables it creates has just tablename and not dbname.tablename?
Thanks to #Craig Ringer for pointing me in the right direction.
Yes, there was SET search_path on the database for the original DB. This created the table names with schema names prefixed to table names.
Removing or commenting those out of the backup script created tables without a schema prefix. Which was desirable. But the restore didn't result in complete restore, and many tables got left out.
So did the restore, with usual means. Tables are created with schema names prefixed. The sql query scripts broke because they were not specifying the schema names every time they queried the table. To fix this, I followed this - https://stackoverflow.com/a/2875705/1945517
ALTER ROLE <your_login_role> SET search_path TO dbname;
This fixed the broken queries.