165 votes

Comment réinitialiser une séquence dans postgres et remplir la colonne id avec de nouvelles données ?

J'ai une table avec plus d'un million de lignes. Je dois réinitialiser la séquence et réaffecter la colonne id avec de nouvelles valeurs (1, 2, 3, 4... etc...). Existe-t-il un moyen simple de le faire ?

8 votes

La vraie question : pourquoi diable voulez-vous faire cela ? On peut supposer que l'ID est la clé primaire, et qu'il n'y a donc aucun avantage à changer la clé primaire. Une clé primaire est une valeur sans signification (dans votre cas, une valeur artificielle). La "renuméroter" ne sert à rien dans une base de données relationnelle.

2 votes

Au départ, l'application fonctionnait localement, puis j'ai copié les données sur la production. Mais id ne commençaient pas à partir de 1. L'ordre s'est donc révélé être le suivant : 150, 151..., 300, 1, 2... Et cela causerait éventuellement des erreurs de duplication d'ids, je suppose, si je n'avais pas renuméroté les ids. De plus, l'ordre par id est généralement meilleure que la commande par created_at . Et voici ce qui a marché pour moi .

0 votes

Le but est de pouvoir continuer à utiliser un entier normal au lieu d'un bigint pour une clé primaire dans une base de données qui continue à incrémenter la clé séquentielle mais qui reçoit constamment de nouvelles données. Vous atteindrez rapidement la limite des entiers signés, et si la conservation de l'identifiant existant n'est pas importante, ce processus vous ramènera à des nombres d'identifiants gérables.

21voto

ivy Points 3780

Les deux solutions proposées n'ont pas fonctionné pour moi ;

> SELECT setval('seq', 0);
ERROR:  setval: value 0 is out of bounds for sequence "seq" (1..9223372036854775807)

setval('seq', 1) commence la numérotation par 2, et ALTER SEQUENCE seq START 1 commence la numérotation avec 2 également, parce que seq.is_called est vrai (Postgres version 9.0.4)

La solution qui a fonctionné pour moi est la suivante :

> ALTER SEQUENCE seq RESTART WITH 1;
> UPDATE foo SET id = DEFAULT;

7voto

alexkovelsky Points 41

Pour conserver l'ordre des rangées :

UPDATE thetable SET rowid=col_serial FROM 
(SELECT rowid, row_number() OVER ( ORDER BY lngid) AS col_serial FROM thetable ORDER BY lngid) AS t1 
WHERE thetable.rowid=t1.rowid;

4voto

Stone Points 205

Pour info : Si vous devez spécifier une nouvelle valeur de départ entre une gamme d'ID (256 - 10000000 par exemple) :

SELECT setval('"Sequence_Name"', 
       (SELECT coalesce(MAX("ID"),255) 
           FROM "Table_Name" 
           WHERE "ID" < 10000000 and "ID" >= 256)+1
       );

3voto

Frank Points 31

Le simple fait de réinitialiser la séquence et de mettre à jour toutes les lignes peut provoquer des erreurs de duplicate id. Dans de nombreux cas, vous devez mettre à jour toutes les lignes deux fois. D'abord avec des identifiants plus élevés pour éviter les doublons, puis avec les identifiants que vous souhaitez réellement.

Veuillez éviter d'ajouter un montant fixe à tous les identifiants (comme recommandé dans d'autres commentaires). Que se passe-t-il si vous avez plus de lignes que ce montant fixe ? En supposant que la valeur suivante de la séquence est supérieure à tous les ids des lignes existantes (vous voulez juste combler les vides), je ferais comme suit :

UPDATE table SET id = DEFAULT;
ALTER SEQUENCE seq RESTART;
UPDATE table SET id = DEFAULT;

2voto

Dans mon cas, j'y suis parvenu avec :

ALTER SEQUENCE table_tabl_id_seq RESTART WITH 6;

Où ma table est nommée tableau

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X