Opened 5 years ago

Last modified 4 years ago

#31730 assigned Bug

manage.py sqlsequencereset not implemented for sqlite3 — at Version 3

Reported by: axil Owned by: nobody
Component: Database layer (models, ORM) Version: dev
Severity: Normal Keywords: sql sequence reset sqlite3
Cc: Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: yes
Easy pickings: no UI/UX: no

Description (last modified by axil)

Currently ./manage.py sqlsequencereset (docs) never prints anything for the sqlite3 backend.

It happens because the function sequence_reset_sql defined in django/django/db/backends/base/operations.py
is not implemented for the sqlite3 backend in django/django/db/backends/sqlite3/operations.py

django/django/contrib/sites/management.py makes use of this function

    # We set an explicit pk instead of relying on auto-incrementation,
    # so we need to reset the database sequence. See #17415.
    sequence_sql = connections[using].ops.sequence_reset_sql(no_style(), [Site])
    if sequence_sql:
        if verbosity >= 2:
             print("Resetting sequence")

Here sequence_reset_sql also does nothing for sqlite3, but sqlite3 is pretty lenient to
the sequences, so it didn't result in an exception.

Same applies to its usage in manage.py loaddata: sqlite3 fixes the sequences automatically.

Leniency of sqlite is also the explanation of how django/tests/backends/tests.py:SequenceResetTest.test_generic_relation
test contrives to pass with sequence_reset_sql being noop for sqlite3.

What it cannot do automatically is reset the sequence to zero as demonstrated in the new test
django/tests/backends/tests.py:SequenceResetTest.test_reset_sequence

    def test_reset_sequence(self):
        Post.objects.create(name='1st post', text='hello world')
    
        Post.objects.all().delete()

        # Reset the sequences for the database
        commands = connections[DEFAULT_DB_ALIAS].ops.sequence_reset_sql(no_style(), [Post])
        with connection.cursor() as cursor:
            for sql in commands:
                cursor.execute(sql)

        # If we create a new object now, it should have a PK greater
        # than the PK we specified manually.
        obj = Post.objects.create(name='New post', text='goodbye world')
        self.assertEqual(obj.pk, 1)

Change History (3)

comment:2 by axil, 5 years ago

The fix is related and partly based on the code from the recent ticket #31479 as well as on the corresponding functions for postgres and oracle.

comment:3 by axil, 5 years ago

Description: modified (diff)
Note: See TracTickets for help on using tickets.
Back to Top