426

I would like to force the auto increment field of a table to some value, I tried with this:

ALTER TABLE product AUTO_INCREMENT = 1453

AND

ALTER SEQUENCE product  RESTART WITH 1453;
ERROR:  relation "your_sequence_name" does not exist

I have a table product with Id and name field

2
  • 7
    If new why not use pgAdmin and inspect the commands it will generate?
    – Unreason
    Commented Mar 17, 2011 at 17:06
  • 3
    Usually tables are named like 'products" and not like a "product". In this case your sequence will be named like "products_id_seq". Be sure that you are looking for a correct sequence. Commented Jun 14, 2017 at 12:02

18 Answers 18

564

If you created the table product with an id column, then the sequence is not simply called product, but rather product_id_seq (that is, ${table}_${column}_seq).

This is the ALTER SEQUENCE command you need:

ALTER SEQUENCE product_id_seq RESTART WITH 1453

You can see the sequences in your database using the \ds command in psql. If you do \d product and look at the default constraint for your column, the nextval(...) call will specify the sequence name too.

13
  • 71
    It's not clear from this message what the correct syntax is. It is: ALTER SEQUENCE product_id_seq RESTART WITH 1453; Commented May 3, 2012 at 22:19
  • 15
    Just because I parsed the above poorly, here's my way of restating the exact same thing. The syntax is ALTER SEQUENCE yourTableName_yourColumnName_seq RESTART WITH #, where "seq" is the literal text, and you put in a number for #. Do not neglect the underscores. :-)
    – kmort
    Commented May 21, 2015 at 17:32
  • 11
    Please note that if not using the public schema it is needed to prefix with my_schema. ALTER SEQUENCE my_schema.product_id_seq RESTART WITH 1453 Commented Apr 10, 2018 at 13:04
  • 22
    Note that the value you restart with is the next value you want to use. So if you already have a record with id 1453, you should RESTART WITH 1454.
    – hughes
    Commented Mar 21, 2019 at 21:58
  • 5
    with IDENTITY column constraints, you do ALTER TABLE tbl ALTER COLUMN id RESTART SET START 1453 Commented Jan 26, 2021 at 10:14
197

The following command does this automatically for you: This will also delete all the data in the table. So be careful.

TRUNCATE TABLE someTable RESTART IDENTITY;
7
  • 55
    Beware - this will delete all of your data as well
    – kibibu
    Commented Oct 6, 2013 at 22:20
  • 37
    @Loolooii, Just flagging it; if somebody unfamiliar to SQL is searching here because they manually added a row to a table with an autoincrement field (through an ORM, for example), then this solution is probably not what they expect.
    – kibibu
    Commented Oct 9, 2013 at 3:15
  • 3
    The TABLE keyword is redundant. TRUNCATE someTable RESTART IDENTITY; is enough.
    – user1
    Commented Oct 3, 2016 at 8:17
  • 10
    @ihossain have you tried TRUNCATE someTable RESTART IDENTITY CASCADE; ?
    – Vedran
    Commented May 31, 2019 at 15:12
  • 3
    For referenced tables you can do TRUNCATE table2, table1 RESTART IDENTITY;
    – Zeeshanef
    Commented Jun 30, 2019 at 9:45
168

Here is the command that you are looking for, assuming your sequence for the product table is product_id_seq:

ALTER SEQUENCE product_id_seq RESTART WITH 1453;
0
70

To set the sequence counter:

setval('product_id_seq', 1453);

If you don't know the sequence name use the pg_get_serial_sequence function:

select pg_get_serial_sequence('product', 'id');
 pg_get_serial_sequence 
------------------------
 public.product_id_seq

The parameters are the table name and the column name.

Or just issue a \d product at the psql prompt:

=> \d product
                         Table "public.product"
 Column |  Type   |                      Modifiers                       
--------+---------+------------------------------------------------------
 id     | integer | not null default nextval('product_id_seq'::regclass)
 name   | text    | 
2
  • 1
    SELECT setval('product_id_seq', 1453); worked for me Commented Apr 22, 2021 at 12:56
  • I'm trying to select pg_get_serial_sequence('Domain.products', 'id'); but complains that schema does not exists. How can I run this query? I'm new with psql.
    – mehul9595
    Commented May 17, 2021 at 10:15
59
-- Change the starting value of the sequence

ALTER SEQUENCE project_id_seq RESTART 3000;

Same but dynamic :

SELECT SETVAL('project_id_seq', (SELECT MAX(id) FROM project));

The use of a SELECT is weird but it works.

Source: https://kylewbanks.com/blog/Adding-or-Modifying-a-PostgreSQL-Sequence-Auto-Increment

Edit: removed +1 as suggested in the comments

4
  • 1
    If I'm not mistaken, PG represents their sequences with last_value and is_called, starts at (1, false), then (1, true), (2, true)... so the MAX(id) + 1 should be MAX(id) instead to not skip an id.
    – Ten
    Commented Jul 17, 2019 at 9:47
  • I also had to restart my postgres instance for this to work. brew services restart postgresql
    – BigRon
    Commented Jan 31, 2020 at 23:00
  • SELECT SETVAL('project_id_seq', (SELECT MAX(id) + 1 FROM project)); Works perfectly But is there a way to reset the increment value to 0. So the new entries begin with a 0 index ? Commented May 25, 2020 at 21:00
  • No need to add +1, just use MAX(column_name). If you add +1, it will skip a value in the sequence.
    – Dima L.
    Commented Sep 20, 2022 at 6:28
25

To set it to the next highest value you can use:

SELECT SETVAL(pg_get_serial_sequence('table_name', 'column_name'), (SELECT MAX(column_name) FROM table_name));
3
  • Most useful answer. Thanks!
    – Ulvi
    Commented Oct 27, 2021 at 8:04
  • 1
    This fit me the best. Make sure to add a +1 to the max() though. That is: SELECT SETVAL(pg_get_serial_sequence('table_name', 'column_name'), (SELECT MAX(column_name) + 1 FROM table_name)); Commented Aug 16, 2022 at 19:30
  • 1
    No need to add +1, just use MAX(column_name). If you add +1, it will skip a value in the sequence.
    – Dima L.
    Commented Sep 20, 2022 at 6:28
19

If you have a table with an IDENTITY column that you want to reset the next value for you can use the following command:

ALTER TABLE <table name> 
    ALTER COLUMN <column name> 
        RESTART WITH <new value to restart with>;
1
  • 5
    One + for usability in case of there's no sequence or you can NOT truncate the table. I think it's best answer
    – ABS
    Commented Sep 18, 2019 at 12:18
17

Converted from comment for the sake of visitor's convenience

It's not clear from this message what the correct syntax is. It is:

ALTER SEQUENCE product_id_seq RESTART WITH 1453;
14

Year 2021, Postgres 11.12

ALTER SEQUENCE did not worked for me, it resets it to null somehow. What worked for me is:

SELECT setval('<table>_<column>_seq', 5);
1
  • it worked for me as well with Postgres 12.8, thanks Commented Nov 18, 2021 at 15:44
12

if you want to Reset auto increment from GUI, then follow this steps.

  1. Go to your Database
  2. Click on Public
  3. in the tables Listing page you can see TABS like 'Tables', 'Views', 'Sequences' like that.
  4. Click on Sequences
  5. when you click on 'Sequences' you can see all the Sequences Listing, click on any that you want to Reset
  6. After that you can see multiple choice like 'Alter', 'Set Value', 'Restart', 'Reset' etc...
  7. then click on Reset, then add one New Row.
1
  • 1
    This worked with DBeaver. Many thanks I don't get why devs just have to complicate things! Commented Oct 4, 2023 at 5:39
7

To reset the auto increment you have to get your sequence name by using following query.

Syntax:

SELECT pg_get_serial_sequence(‘tablename’, ‘ columnname‘);

Example:

SELECT pg_get_serial_sequence('demo', 'autoid');

The query will return the sequence name of autoid as "Demo_autoid_seq" Then use the following query to reset the autoid

Syntax:

ALTER SEQUENCE sequenceName RESTART WITH value;

Example:

ALTER SEQUENCE "Demo_autoid_seq" RESTART WITH 1453;
5

To get sequence id use

SELECT pg_get_serial_sequence('tableName', 'ColumnName');

This will gives you sequesce id as tableName_ColumnName_seq

To Get Last seed number use

select currval(pg_get_serial_sequence('tableName', 'ColumnName'));

or if you know sequence id already use it directly.

select currval(tableName_ColumnName_seq);

It will gives you last seed number

To Reset seed number use

ALTER SEQUENCE tableName_ColumnName_seq RESTART WITH 45
5

Use this query to check what is the Sequence Key with Schema and Table,

SELECT pg_get_serial_sequence('"SchemaName"."TableName"', 'KeyColumnName'); // output: "SequenceKey"

Use this query increase increment value one by one,

SELECT nextval('"SchemaName"."SequenceKey"'::regclass); // output 110

When inserting to table next incremented value will be used as the key (111).

Use this query to set specific value as the incremented value

SELECT setval('"SchemaName"."SequenceKey"', 120);

When inserting to table next incremented value will be used as the key (121).

1
  • Thanks for pointing out how to get seqName for different schema :) Commented Dec 17, 2021 at 4:02
5
ALTER SEQUENCE public."Table_Id_seq"
RESTART 50;

this query worked for me. Postgresql version 14

1
  • 1
    I needed to use quotes ", only this way it worked Postgresql version 16. I didn't need to use public. and also be careful it is case sensitive, so in this case table_Id_seq or Table_id_seq will not work. If you use pgAdmin you can see all your sequence names in Schemas > public > Sequences.
    – milos
    Commented Nov 22, 2023 at 22:32
4

I am not sure about all of the above answers, What if I don't have a sequence name? What if I don't want to truncate my table?

Below query helped me to do that without affecting the existing data.

ALTER TABLE <<table_name>>
    ALTER COLUMN <<primary_key_column_name>> RESTART SET START 4044;
3

If table is like

bigint NOT NULL GENERATED ALWAYS AS IDENTITY ( INCREMENT 1 START 0)

After inserting some records in the range of 0-9, will cause conflict for next insert, so to reset the START:

ALTER TABLE ... ALTER COLUMN ... RESTART WITH 10;
1

Node script: Fix all tables identity: auto-increment / nextval, based on last inserted it.

const pg = require('pg');
const { Client } = pg;

const updateTables = async () => {

  const client = new Client({
    user: 'postgres',
    host: 'localhost',
    database: 'my-database',
    password: 'postgres',
    port: 5432,
  });

  await client.connect();

  console.log('Connected');

  const execQuery = async (queryStr, params = []) => {
    return new Promise((resolve, reject) => {
      client.query(queryStr, params, (error, results) => {
        if (error) {
          reject(error);
        } else {
          resolve(results);
        }
      })
    })
  }

  const tablesRes = await execQuery(`
    SELECT table_name
    FROM information_schema.tables
    WHERE table_type='BASE TABLE'
    AND table_schema='public';
  `)

  const tables = tablesRes.rows.map(row => row.table_name);

  tables.map(async tableName => {
    let lastId;
    try {
      const res = await execQuery(`SELECT id from "${tableName}" ORDER BY id DESC LIMIT 1`);
      lastId = res.rows[0].id;
    } catch (e) {}

    if (lastId) {
      const nextId = lastId + 1;
      const queryStr = `ALTER SEQUENCE ${tableName}_id_seq RESTART WITH ${nextId}`;
      await execQuery(queryStr);
      console.log(tableName, queryStr);
    }
  })

};

updateTables();
0

Note that if you have table name with '_', it is removed in sequence name.

For example, table name: user_tokens column: id Sequence name: usertokens_id_seq

1
  • That's not the case for me. I have the same condition but the underscore is preserved in the name of the sequence name
    – Ulvi
    Commented Oct 27, 2021 at 7:55

Not the answer you're looking for? Browse other questions tagged or ask your own question.