Il y a beaucoup de bonnes réponses ici. J'ai eu le même besoin après avoir rechargé ma base de données Django.
Mais j'en avais besoin :
- Fonction tout en un
- Possibilité de corriger un ou plusieurs schémas à la fois
- On peut réparer toutes les tables ou seulement une à la fois.
- Je voulais aussi un moyen agréable de voir exactement ce qui avait changé, ou pas changé.
Cela semble très similaire à ce que la demande initiale était pour.
Merci à Baldiry et Mauro de m'avoir mis sur la bonne voie.
drop function IF EXISTS reset_sequences(text[], text) RESTRICT;
CREATE OR REPLACE FUNCTION reset_sequences(
in_schema_name_list text[] = '{"django", "dbaas", "metrics", "monitor", "runner", "db_counts"}',
in_table_name text = '%') RETURNS text[] as
$body$
DECLARE changed_seqs text[];
DECLARE sequence_defs RECORD; c integer ;
BEGIN
FOR sequence_defs IN
select
DISTINCT(ccu.table_name) as table_name,
ccu.column_name as column_name,
replace(replace(c.column_default,'''::regclass)',''),'nextval(''','') as sequence_name
from information_schema.constraint_column_usage ccu,
information_schema.columns c
where ccu.table_schema = ANY(in_schema_name_list)
and ccu.table_schema = c.table_schema
AND c.table_name = ccu.table_name
and c.table_name like in_table_name
AND ccu.column_name = c.column_name
AND c.column_default is not null
ORDER BY sequence_name
LOOP
EXECUTE 'select max(' || sequence_defs.column_name || ') from ' || sequence_defs.table_name INTO c;
IF c is null THEN c = 1; else c = c + 1; END IF;
EXECUTE 'alter sequence ' || sequence_defs.sequence_name || ' restart with ' || c;
changed_seqs = array_append(changed_seqs, 'alter sequence ' || sequence_defs.sequence_name || ' restart with ' || c);
END LOOP;
changed_seqs = array_append(changed_seqs, 'Done');
RETURN changed_seqs;
END
$body$ LANGUAGE plpgsql;
Ensuite, cliquez sur Exécuter et voyez les changements s'exécuter :
select *
from unnest(reset_sequences('{"django", "dbaas", "metrics", "monitor", "runner", "db_counts"}'));
Renvoie à
activity_id_seq restart at 22
api_connection_info_id_seq restart at 4
api_user_id_seq restart at 1
application_contact_id_seq restart at 20
1 votes
Je suis curieux est-ce que vous laissez tomber la base de données avant de faire une restauration ? Je me souviens vaguement que cela s'est produit, mais je peux me tromper :P
39 votes
Le wiki de PostgreSQL a une page sur Correction des séquences .
26 votes
Juste pour aider à la googlelisation, le message d'erreur envoyé ici est : "La valeur de la clé dupliquée viole la contrainte d'unicité..."
5 votes
Voici comment sqlsequencereset dans Django le fait : SELECT setval(pg_get_serial_sequence("<nom_table>", 'id'), coalesce(max("id"), 1), max("id") IS NOT null) FROM "<nom_table>" ;
1 votes
La première instance du <nom de la table> doit être entourée de guillemets simples pour que la fonction pg_get_serioal_sequence fonctionne : SELECT setval(pg_get_serioal_sequence('<nom_table>', 'id'), coalesce(max("id"), 1), max("id") IS NOT null) FROM "<nom_table>"
0 votes
Question connexe : stackoverflow.com/questions/62059947/
0 votes
stackoverflow.com/questions/244243/