6
votes

PostgreSQL Nextval générant des valeurs existantes

J'ai dû migrer d'une application Ruby sur Ruby basée sur MySQL pour utiliser PostgreSQL. Pas de problèmes mais un à ce jour, et je ne sais pas comment résoudre.

La migration des données a apporté des identifiants avec elle et PostgreSQL a maintenant des problèmes avec les identifiants existants: ce n'est pas clair pour moi où il reçoit la valeur qu'il utilise pour déterminer la base pour NextVal: ce n'est certainement pas le plus élevé Valeur dans la colonne, bien que vous puissiez penser que ce serait une bonne idée. En tout cas, il collectionne maintenant avec les valeurs d'identification existantes. Colonne ID, créée à partir d'une migration standard ROR est définie comme P>

'select max(id) from <table_name>' 


0 commentaires

5 Réponses :


1
votes

PG utilise des séquences:

Faites sa valeur actuelle 1 supérieure à la valeur la plus élevée de votre table comme celle-ci. xxx

voir aussi ces

http://www.postgresql.org/docs/8.4/interactive/dataType-numeric.html#daTaType-Serial

< Un href = "http://www.postgresql.org/docs/8.4/interactive/fonctions-Equence.html" rel = "nOfollow noreferrer"> http://www.postgresql.org/docs/8.4/interactive/functions -Sucidence.html


0 commentaires

0
votes

Utilisez SETVAL () pour définir la valeur de départ pour la séquence.


0 commentaires

3
votes

Avec cette définition, la colonne obtiendra la valeur suivante de la séquence Geopoints_id_seq. Cette séquence n'est pas directement attachée à la table. Si vous migrez des données, vous devez créer ou mettre à jour cette séquence afin que son point de départ soit supérieur à l'ID max actuel de votre table.

Vous devriez pouvoir définir sa nouvelle valeur avec par exemple P>

   ALTER SEQUENCE geopoints_id_seq RESTART with 1692;


0 commentaires

11
votes

Il y a un réinitialiser_pk_réquences! méthode sur le Adaptateur Postgres . Vous pouvez l'appeler et cela le mettra à max (ID) + 1, ce qui est probablement ce que vous voulez.

Dans certains projets, je reçois des données etl'ed assez souvent pour justifier une tâche de râteau pour le faire pour tous les modèles , ou pour un modèle spécifié. Voici la tâche - incluez-la dans certains microsphiles ou de ses propres tâches: xxx

Vous pouvez exécuter cela soit pour tous les modèles (définis sous Rais_root / app / modèles ) Utilisation de RAQUER RESET_EFENCIENCESSES ou pour un modèle spécifique en passant dans un nom de classe.


3 commentaires

WOW, merci pour les réponses rapides et utiles. Je vais faire une course à la solution @Hgimenez, car je suis dans un environnement de rails, mais je présume que le message est que je peux le faire via une ligne de commande à Postgres. En suivant: Je vais essayer cela, mais puis-je mettre une telle déclaration dans une migration?


Certainement, vous pouvez avoir une migration qui va: ActiveRecord :: base.connection.reeset_pk_srequence! ('Nom de table »), mais cela peut certainement être effectué à partir de PSQL.


Joli. Merci de votre aide.



5
votes

La version Rails 3 ressemble à ceci: xxx

https://gist.github.com/ 909032


1 commentaires

Je pense que rails_root doit être rails.root.to_s à la place. De plus, la syntaxe Task est obsolète. Je pense que cela devrait être tâche: réinissification, [: model_class] => [: environnement]