9

(PostgreSQL 9.4)

I am in the process of migrating an older database to a new schema. After using pg_restore to acquire the new schema (without data) from my development machine, I find that some sequences do not start at 1. (I had changed multiple sequences during development to work with higher values).

Before I start the database migration, is there a programmatic way of resetting all the sequences (some of which are not primary keys) back to 1?

Thanks for any help or suggestions.

2
  • "programmatic way of resetting all the sequences" what you mean? You can use ALTER SEQUENCE table_name_id_seq START WITH 1; Commented Dec 12, 2016 at 14:23
  • @M.Wiśnicki True...one table at a time. But I am needing a psql script that will reset ALL sequences in the database -- including those that are independent of any table. (I have over a hundred tables with about 150 sequences). Thanks. Commented Dec 12, 2016 at 18:55

4 Answers 4

18

This works simple enough for my needs, SETVAL manual. In PgAdmin where I want to restrict the sequences to all those in the public schema:

SELECT  SETVAL(c.oid, 1)
from pg_class c JOIN pg_namespace n 
on n.oid = c.relnamespace 
where c.relkind = 'S' and n.nspname = 'public'  

I post this as a help to anyone coming here.

Sign up to request clarification or add additional context in comments.

1 Comment

Worth mentionning that there is an optional 3rd argument in the setval() function. When set to false nextval will return 1, otherwise it would have returned 2.
6

You can change seq value using setval in loop, here you get all tables whith columns Id in DATA_BASE_NAME

DO $$
DECLARE
i TEXT;
BEGIN
 FOR i IN (SELECT tb.table_name FROM information_schema.tables AS tb INNER JOIN information_schema.columns AS cols ON 
        tb.table_name = cols.table_name WHERE tb.table_catalog='DATA_BASE_NAME' 
         AND tb.table_schema='public' AND cols.column_name='Id') LOOP
         EXECUTE 'SELECT setval('||'"' || i || '_Id_seq"'||',1);';

  END LOOP;
END $$;

1 Comment

Thanks. I was just thinking about using the information_schema.
2

You can do it with this sql code:

DO $$
DECLARE
i TEXT;
BEGIN
 FOR i IN (SELECT column_default FROM information_schema.columns WHERE column_default SIMILAR TO 'nextval%') 
  LOOP
         EXECUTE 'ALTER SEQUENCE'||' ' || substring(substring(i from '''[a-z_]*')from '[a-z_]+') || ' '||' RESTART 1;';    
  END LOOP;
END $$; 

I read information of columns and I use regex to separate squence's name. After I make query and use EXECUTE for each sequence. This code is for all sequences of your DB.

1 Comment

a little improvement to take care of columns with numbers in their names i from '''[a-z0-9_]*') from '[a-z0-9_
0

Sometimes the sequences do not follow a pattern.
I share the following code I hope it helps

CREATE OR REPLACE FUNCTION
 restore_sequences(schema_name in varchar)
 RETURNS void AS $$
 DECLARE
    statements CURSOR FOR
        select s.sequence_schema, s.sequence_name from 
        information_schema."sequences" s
        where s.sequence_schema = schema_name
        order by s.sequence_schema asc;
BEGIN
    FOR stmt IN statements loop
        execute 'SELECT SETVAL(' || ((E'\''||(select current_database())||'.'||stmt.sequence_schema||'.'||stmt.sequence_name)||(E'\'')) || ', 1, true);';
        execute 'ALTER SEQUENCE ' || ((select current_database())||'.'||stmt.sequence_schema||'.'||stmt.sequence_name) || ' START 1';
    END LOOP;
END;
$$ LANGUAGE plpgsql
;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.