How to reset the sequence for IDs on PostgreSQL tables

Solution 1:

Run sqlsequencereset and it'll print all the reset commands you need.

Solution 2:

As suggested by "Dmitry Shevchenko" you can run sqlsequencereset to solve your problem.

or

You can execute the SQL query generated by sqlsequencereset from within python in this way (using the default database):

from django.core.management.color import no_style
from django.db import connection

from myapps.models import MyModel1, MyModel2


sequence_sql = connection.ops.sequence_reset_sql(no_style(), [MyModel1, MyModel2])
with connection.cursor() as cursor:
    for sql in sequence_sql:
        cursor.execute(sql)

I tested this code with Python3.6, Django 2.0 and PostgreSQL 10.

Solution 3:

Here's a short snippet to reset all sequences in Django 1.9+ (based on http://djangosnippets.org/snippets/2774/) and compatible with Python 3:

import os
from io import StringIO

os.environ['DJANGO_COLORS'] = 'nocolor'

from django.core.management import call_command
from django.apps import apps
from django.db import connection

commands = StringIO()
cursor = connection.cursor()

for app in apps.get_app_configs():
    label = app.label
    call_command('sqlsequencereset', label, stdout=commands)

cursor.execute(commands.getvalue())

Solution 4:

So the quickest, easiest and most "Django" way to do this in my opinion is to use the following management command:

python manage.py sqlsequencereset app_name

After this, you'll get something such as:

BEGIN;
SELECT setval(pg_get_serial_sequence('"measurements_quantity"','id'), coalesce(max("id"), 1), max("id") IS NOT null) FROM "measurements.Quantities";
SELECT setval(pg_get_serial_sequence('"measurements.Prefixes"','id'), coalesce(max("id"), 1), max("id") IS NOT null) FROM "measurements.Prefixes";
COMMIT;

The next step is to run this in the python manage.py dbshell management command, so run this and then you'll see the interaction database shell in your terminal:

psql (11.7 (Debian 11.7-0+deb10u1), server 11.5 (Debian 11.5-1.pgdg90+1))
Type "help" for help.

postgres=# BEGIN;
BEGIN
postgres=# SELECT setval(pg_get_serial_sequence('"measurements.Quantities"','id'), coalesce(max("id"), 1), max("id") IS NOT null) FROM "measurements.Quantities";
 setval 
--------
      1
(1 row)

postgres=# SELECT setval(pg_get_serial_sequence('"measurements.Prefixes"','id'), coalesce(max("id"), 1), max("id") IS NOT null) FROM "measurements.Prefixes";
 setval 
--------
      1
(1 row)

postgres=# COMMIT;
COMMIT
postgres=# exit

Simple as that. The python manage.py sqlsequencereset app_name command will give you the SQL you need to run, and you run it in the dbshell.

No writing your own custom SQL or custom code and it will give you what you need in the correct format and db engine of choice.

Solution 5:

PostgreSQL Command: ALTER SEQUENCE app_model_id_seq RESTART WITH 1