[postgresql] PostgreSQL Error: Relation already exists

I am trying to create a table that was dropped previously.

But when I do the CREATE TABLE A ... I am getting below error:

Relation 'A' already exists.

I verified doing SELECT * FROM A, but then I got another error:

Relation 'A' does not exists.

I already tried to find it in \dS+ listing all relations, and it is not there.
To complicate this, I have tested this by creating this table in another database and I got the same error. I am thinking that could be an error when this table was dropped. Any ideas?

Here is the code: I'm using a generated code from Power SQL. I have the same error without using the sequence. It just works when I change the name and in this case I can not do that.

CREATE SEQUENCE csd_relationship_csd_relationship_id_seq;
CREATE TABLE csd_relationship (
    csd_relationship_id INTEGER NOT NULL DEFAULT nextval('csd_relationship_csd_relationship_id_seq'::regclass),  
    type_id INTEGER NOT NULL,
    object_id INTEGER NOT NULL,
    CONSTRAINT csd_relationship PRIMARY KEY (csd_relationship_id)
);

This question is related to postgresql identifier create-table

The answer is


Another reason why you might get errors like "relation already exists" is if the DROP command did not execute correctly.

One reason this can happen is if there are other sessions connected to the database which you need to close first.


In my case I was migrating from 9.5 to 9.6. So to restore a database, I was doing :

sudo -u postgres psql -d databse -f dump.sql

Of course it was executing on the old postgreSQL database where there are datas! If your new instance is on port 5433, the correct way is :

sudo -u postgres psql -d databse -f dump.sql -p 5433

There should be no single quotes here 'A'. Single quotes are for string literals: 'some value'.
Either use double quotes to preserve the upper case spelling of "A":

CREATE TABLE "A" ...

Or don't use quotes at all:

CREATE TABLE A ...

which is identical to

CREATE TABLE a ...

because all unquoted identifiers are folded to lower case automatically in PostgreSQL.


You could avoid problems with the index name completely by using simpler syntax:

CREATE TABLE csd_relationship (
    csd_relationship_id serial PRIMARY KEY,
    type_id integer NOT NULL,
    object_id integer NOT NULL
);

Does the same as your original query, only it avoids naming conflicts automatically. It picks the next free identifier automatically. More about the serial type in the manual.


In my case, I had a sequence with the same name.


You cannot create a table with a name that is identical to an existing table or view in the cluster. To modify an existing table, use ALTER TABLE (link), or to drop all data currently in the table and create an empty table with the desired schema, issue DROP TABLE before CREATE TABLE.

It could be that the sequence you are creating is the culprit. In PostgreSQL, sequences are implemented as a table with a particular set of columns. If you already have the sequence defined, you should probably skip creating it. Unfortunately, there's no equivalent in CREATE SEQUENCE to the IF NOT EXISTS construct available in CREATE TABLE. By the looks of it, you might be creating your schema unconditionally, anyways, so it's reasonable to use

DROP TABLE IF EXISTS csd_relationship;
DROP SEQUENCE IF EXISTS csd_relationship_csd_relationship_id_seq;

before the rest of your schema update; In case it isn't obvious, This will delete all of the data in the csd_relationship table, if there is any


In my case, it wasn't until I PAUSEd the batch file and scrolled up a bit, that wasn't the only error I had gotten. My DROP command had become DROP and so the table wasn't dropping in the first place (thus the relation did indeed still exist). The  I've learned is called a Byte Order Mark (BOM). Opening this in Notepad++, re-save the SQL file with Encoding set to UTM-8 without BOM and it runs fine.


Sometimes this kind of error happens when you create tables with different database users and try to SELECT with a different user. You can grant all privileges using below query.

GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA schema_name TO username;

And also you can grant access for DML statements

GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA schema_name TO username;

Examples related to postgresql

Subtracting 1 day from a timestamp date pgadmin4 : postgresql application server could not be contacted. Psql could not connect to server: No such file or directory, 5432 error? How to persist data in a dockerized postgres database using volumes input file appears to be a text format dump. Please use psql Postgres: check if array field contains value? Add timestamp column with default NOW() for new rows only Can't connect to Postgresql on port 5432 How to insert current datetime in postgresql insert query Connecting to Postgresql in a docker container from outside

Examples related to identifier

Are PostgreSQL column names case-sensitive? getting the error: expected identifier or ‘(’ before ‘{’ token How to call on a function found on another file? Hibernate error: ids for this class must be manually assigned before calling save(): PostgreSQL Error: Relation already exists Using number as "index" (JSON) How does jQuery work when there are multiple elements with the same ID value? Hibernate throws org.hibernate.AnnotationException: No identifier specified for entity: com..domain.idea.MAE_MFEView What is the meaning of single and double underscore before an object name?

Examples related to create-table

Field 'id' doesn't have a default value? MySQL: Error Code: 1118 Row size too large (> 8126). Changing some columns to TEXT or BLOB Create hive table using "as select" or "like" and also specify delimiter #1064 -You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version C# - Create SQL Server table programmatically How do I create a table based on another table Creating new table with SELECT INTO in SQL create table in postgreSQL PostgreSQL Error: Relation already exists Mysql: Setup the format of DATETIME to 'DD-MM-YYYY HH:MM:SS' when creating a table