PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

ERREUR :plusieurs séquences possédées trouvées dans Postgres

Mise à jour : Ce bogue a été corrigé dans PostgreSQL v12 avec commit 19781729f78 .
Le reste de la réponse est pertinent pour les anciennes versions.

Un serial la colonne a une séquence qui appartient à la colonne et un DEFAULT valeur qui obtient la valeur de séquence nette.

Si vous essayez de changer cette colonne en une colonne d'identité, vous obtiendrez une erreur indiquant qu'il existe déjà une valeur par défaut pour la colonne.

Maintenant, vous devez avoir supprimé la valeur par défaut, mais pas la séquence qui appartient au serial colonne. Ensuite, lorsque vous avez converti la colonne en une colonne d'identité, une deuxième séquence appartenant à la colonne a été créée.

Désormais, lorsque vous essayez d'insérer une ligne, PostgreSQL essaie de trouver et d'utiliser la séquence appartenant à la colonne, mais il y en a deux, d'où le message d'erreur.

Je dirais qu'il s'agit d'un bogue dans PostgreSQL :à mon avis, il aurait dû soit réutiliser la séquence existante pour la colonne d'identité, soit vous donner une erreur indiquant qu'il existe déjà une séquence appartenant à la colonne, et vous devriez la supprimer. Je vais essayer de corriger ce bogue .

Pendant ce temps, vous devez supprimer manuellement la séquence laissée par le serial colonne.Exécutez la requête suivante :

SELECT d.objid::regclass
FROM pg_depend AS d
   JOIN pg_attribute AS a ON d.refobjid = a.attrelid AND
                             d.refobjsubid = a.attnum
WHERE d.classid = 'pg_class'::regclass
  AND d.refclassid = 'pg_class'::regclass
  AND d.deptype <> 'i'
  AND a.attname = 'patientid'
  AND d.refobjid = 'patient'::regclass;

Cela devrait vous donner le nom de la séquence laissée par le serial colonne. Déposez-le et la colonne d'identité devrait se comporter comme vous le souhaitez.