web-dev-qa-db-fra.com

Erreur PostgreSQL: La relation existe déjà

J'essaie de créer une table qui a été supprimée précédemment. 

Mais quand je fais le CREATE TABLE A ... Je reçois une erreur ci-dessous: 

La relation 'A' existe déjà.

J'ai vérifié en faisant SELECT * FROM A, mais j'ai eu une autre erreur: 

La relation 'A' n'existe pas.

J'ai déjà essayé de le trouver dans \dS+ en listant toutes les relations, et ce n'est pas là.
.__ Pour compliquer les choses, j'ai testé cela en créant cette table dans une autre base de données et j'ai eu la même erreur. Je pense que cela pourrait être une erreur lorsque ce tableau a été supprimé. Des idées?

Voici le code: J'utilise un code généré par Power SQL. J'ai la même erreur sans utiliser la séquence. Cela fonctionne juste quand je change le nom et dans ce cas je ne peux pas faire cela.

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)
);
32
nsbm

J'ai finalement découvert l'erreur. Le problème est que le nom de la contrainte de clé primaire est égal au nom de la table. Je ne sais pas comment postgres représente des contraintes, mais je pense que l'erreur "La relation existe déjà" a été déclenchée lors de la création de la contrainte de clé primaire car la table était déjà déclarée. Mais à cause de cette erreur, la table n'a pas été créée à la fin.

30
nsbm

Il ne devrait y avoir aucune citation ici 'A'. Les guillemets simples sont destinés aux littéraux de chaîne: 'some value'.
Utilisez des guillemets doubles pour conserver l’orthographe en majuscule "A":

CREATE TABLE "A" ...

Ou n'utilisez pas de guillemets du tout:

CREATE TABLE A ...

qui est identique à

CREATE TABLE a ...

parce que tous les identifiants sans guillemets sont repliés automatiquement en minuscules automatiquement dans PostgreSQL .


Vous pouvez éviter complètement les problèmes avec le nom de l'index en utilisant une syntaxe plus simple:

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

Fait la même chose que votre requête initiale, elle évite uniquement les conflits de noms automatiquement. Il sélectionne automatiquement le prochain identifiant libre. Plus d'informations sur le type série dans le manuel .

12
Erwin Brandstetter

Vous ne pouvez pas créer une table avec un nom identique à une table ou une vue existante du cluster. Pour modifier une table existante, utilisez ALTER TABLE (link) , ou pour supprimer toutes les données présentes dans la table et créer une table vide avec le schéma souhaité, émettez DROP TABLE avant CREATE TABLE.

Il se peut que la séquence que vous créez soit le coupable. Dans PostgreSQL, les séquences sont implémentées sous forme de table avec un ensemble particulier de colonnes. Si vous avez déjà défini la séquence, vous devez probablement ignorer sa création. Malheureusement, il n'y a pas d'équivalent dans CREATE SEQUENCE à la construction IF NOT EXISTS disponible dans CREATE TABLE. En apparence, vous créez peut-être votre schéma inconditionnellement, de toute façon, il est donc raisonnable d’utiliser 

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

avant le reste de la mise à jour de votre schéma; Si cela n’est pas évident, Ceci supprimera toutes les données de la table csd_relationship, s’il en existe

Dans mon cas, j'ai eu une séquence du même nom.

3
Dave Van den Eynde

Une autre raison pour laquelle vous pourriez recevoir des erreurs telles que "la relation existe déjà" est si la commande DROP ne s'est pas exécutée correctement.

Cela peut s’expliquer par le fait que vous devez d’abord fermer les autres sessions connectées à la base de données.

2
isedwards

Dans mon cas, ce n’est que lorsque j’ai mis en pause le fichier de commandes et que j’ai fait défiler un peu, ce n’était pas la seule erreur que j’ai eue. Ma commande DROP était devenue DROP et la table ne chutait donc pas (la relation existait donc toujours). Le  que j'ai appris s'appelle une marque d'ordre d'octet (BOM). En ouvrant cela dans Notepad ++, réenregistrez le fichier SQL avec le codage défini sur UTM-8 sans nomenclature et tout se passera bien.

2
user5775085

Dans mon cas, je migrais de 9.5 à 9.6 . Donc, pour restaurer une base de données, je faisais:

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

Bien sûr, il s’exécutait sur l’ancienne base de données postgreSQL où il y avait des données! Si votre nouvelle instance est sur le port 5433, la méthode correcte est la suivante:

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