Reputation: 3737
Using pyscopg2, as Django database default backend, and with very simple case for a test. It fails trying to create a user, with a IntegrityError exception
$ python manage.py test project.core.tests
nosetests --verbosity 1 project.core.tests --rednose
Creating test database for alias 'default'...
X.
-----------------------------------------------------------------------------
1) ERROR: Tests that a user with a sha1 hashed password is change to newer hash method
Traceback (most recent call last):
crowddeals/core/tests.py line 7 in setUp
self.user1 = User.objects.create_user('user1', '[email protected]')
env/lib/python2.7/site-packages/django/contrib/auth/models.py line 160 in create_user
user.save(using=self._db)
env/lib/python2.7/site-packages/django/db/models/base.py line 477 in save
force_update=force_update, update_fields=update_fields)
env/lib/python2.7/site-packages/django/db/models/base.py line 572 in save_base
result = manager._insert([self], fields=fields, return_id=update_pk, using=using, raw=raw)
env/lib/python2.7/site-packages/django/db/models/manager.py line 203 in _insert
return insert_query(self.model, objs, fields, **kwargs)
env/lib/python2.7/site-packages/django/db/models/query.py line 1588 in insert_query
return query.get_compiler(using=using).execute_sql(return_id)
env/lib/python2.7/site-packages/django/db/models/sql/compiler.py line 911 in execute_sql
cursor.execute(sql, params)
env/lib/python2.7/site-packages/django/db/backends/postgresql_psycopg2/base.py line 52 in execute
return self.cursor.execute(query, args)
IntegrityError: duplicate key value violates unique constraint "auth_user_pkey"
DETAIL: Key (id)=(1) already exists.
The default database is working, and is possible to add users. The tests fails just on the test database.
Looking at the test database, I see that the auto increment sequences for the primary keys for all tables has wrong start values, it takes the last used value from the default database as the start values on the test database.
For the default database, the User.id use the auto increment sequence.
CREATE SEQUENCE auth_user_id_seq
INCREMENT 1
MINVALUE 1
MAXVALUE 9223372036854775807
START 1
CACHE 1;
And for the test database creates
CREATE SEQUENCE auth_user_id_seq
INCREMENT 1
MINVALUE 1
MAXVALUE 9223372036854775807
START 2
CACHE 1;
This is obviously wrong, this happens also on other tables, as permissions.
CREATE SEQUENCE auth_permission_id_seq
INCREMENT 1
MINVALUE 1
MAXVALUE 9223372036854775807
START 191
CACHE 1;
I can't guess why this is happening, it has to create the sequences on the new test database starting from 1.
If I change the database engine backend to sqlite3, the exception don't happen. This just happens in postgresql.
How can I fix this? so my tests can start working again.
Upvotes: 4
Views: 1646
Reputation: 2722
If you don't recreate the db with every test, then you've have to reset the sequences yourself.
Also, I think that the sequence definition you've posted were found when inspecting the db after the tests run with a db tool. In that case, I think your db tool is presenting you the SQL to create the sequence as it is: after it's been used.
The fact that it doesn't happen on sqlite has to do with it using a in-memory db by default. Therefore, it's being re-created in every test run.
Upvotes: 1