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

PostgreSQL :Violation unique :7 ERREUR :la valeur de clé en double viole la contrainte unique users_pkey

Postgres gère l'incrémentation automatique un peu différemment de MySQL. Dans Postgres, lorsque vous créez le serial champ, vous créez également un champ de séquence qui garde une trace de l'identifiant à utiliser. Ce champ de séquence va commencer avec une valeur de 1.

Lorsque vous insérez un nouvel enregistrement dans la table, si vous ne spécifiez pas l'id champ, il utilisera la valeur de la séquence, puis incrémentera la séquence. Cependant, si vous spécifiez le id champ, alors la séquence n'est pas utilisée et elle n'est pas non plus mise à jour.

Je suppose que lorsque vous êtes passé à Postgres, vous avez créé ou importé des utilisateurs existants, ainsi que leurs identifiants existants. Lorsque vous avez créé ces enregistrements d'utilisateurs avec leurs identifiants, la séquence n'a pas été utilisée et n'a donc jamais été mise à jour.

Ainsi, si, par exemple, vous avez importé 10 utilisateurs, vous avez des utilisateurs avec les identifiants 1-10, mais votre séquence est toujours à 1. Lorsque vous essayez de créer un nouvel utilisateur sans spécifier l'identifiant, il extrait la valeur de la séquence ( 1), et vous obtenez une violation unique car vous avez déjà un utilisateur avec l'identifiant 1.

Pour résoudre le problème, vous devez définir votre users_id_seq valeur de séquence au MAX(id) de vos utilisateurs existants. Vous pouvez lire cette question/réponse pour plus d'informations sur la réinitialisation de la séquence, mais vous pouvez également essayer quelque chose comme (non testé) :

SELECT setval(pg_get_serial_sequence('users', 'id'), coalesce(max(id)+1, 1), false) FROM users;

Pour votre information, ce n'est pas un problème dans MySQL car MySQL met automatiquement à jour la séquence d'incrémentation automatique à la plus grande valeur de colonne lorsqu'une valeur est insérée manuellement dans le champ d'incrémentation automatique.