The error is harmless but to get rid of it, I think you need to break this restore into two commands, as in:
dropdb -U postgres mydb && \
pg_restore --create --dbname=postgres --username=postgres pg_backup.dump
The --clean
option in pg_restore doesn't look like much but actually raises non-trivial problems.
For versions up to 9.1
The combination of --create
and --clean
in pg_restore options used to be an error in older PG versions (up to 9.1). There is indeed some contradiction between (quoting the 9.1 manpage):
--clean
Clean (drop) database objects before recreating them
and
--create
Create the database before restoring into it.
Because what's the point of cleaning inside a brand-new database?
Starting from version 9.2
The combination is now accepted and the doc says this (quoting the 9.3 manpage):
--clean
Clean (drop) database objects before recreating them. (This might generate some harmless error messages, if any objects were not present in the destination database.)
--create
Create the database before restoring into it. If --clean is also specified, drop and recreate the target database before connecting to it.
Now having both together leads to this kind of sequence during your restore:
DROP DATABASE mydb;
...
CREATE DATABASE mydb WITH TEMPLATE = template0... [other options]
...
CREATE SCHEMA public;
...
CREATE TABLE...
There is no DROP
for each individual object, only a DROP DATABASE
at the beginning. If not using --create
this would be the opposite.
Anyway this sequence raises the error of public
schema already existing because creating mydb
from template0
has imported it already (which is normal, it's the point of a template database).
I'm not sure why this case is not handled automatically by pg_restore
. Maybe this would cause undesirable side-effects when an admin decides to customize template0
and/or change the purpose of public
, even if we're not supposed to do that.
When dumping a schema with the mentioned command, as postgres user:
pg_dump -f file.sql -F plain --inserts -n schemaname database
it produces a file whose basic structure looks like:
-- various SET commands
CREATE SCHEMA schemaname;
ALTER SCHEMA schemaname OWNER TO ownername;
SET search_path = schemaname, pg_catalog;
CREATE TABLE tablename(...) ...
ALTER TABLE schemaname.tablename OWNER TO ownername;
COPY tablename (columns...) FROM stdin;
data...
\.
The fact that search_path
is set to the newly created schema implies that the CREATE TABLE
and COPY
statements that follow will happen in that schema and not in the public
schema.
Or SET search_path
would have to fail, which shouldn't happen even if the creation of the schema just above in the script failed. If schemaname
does not exist, the next schema tried would be pg_catalog
and CREATE TABLE
would refuse to write into it, and after that there's no next schema in the search path, and in particular not public
.
It's hard to imagine what mishappening could cause the above script to end up creating and populating anything in the public
schema.
Best Answer
Short answer
You are actually using (at least) two databases. You are installing
CITEXT
in the wrong one.Longer answer
In the first database (whose name is not shown), you install
CITEXT
. This database is probably thepostgres
database, which is created by default when you install PostgreSQL.Then you use the
\c
command and you switch to another database (sensordata
). You need to create your extension in this database.That is, you should do:
If you need to use the
citext
module in more databases, you need to install it in each one. The extensions on the other databases don't matter. Databases do not interfere with each other.Every PostgreSQL cluster (=database installation) has (by default) one database named
postgres
. If you usepsql
, it is the one to which you connect "by default". You don't actually need to have apostgres
database. I guess thepostgres
database is where you installed theCITEXT
extension.Within every PostgreSQL database, there is, by default, one public schema.
PostgreSQL does not work like (for instance) MySQL, where you can acces several databases at once through a single connection (provided you have a user with the right permissions).
In PostgreSQL you access one database through a single connection. Within a database, you can access as many schemas as needed. The role that schemas play in PostgreSQL is nearly the same as the one played by a database in MySQL.
See also: