I am testing out a small app where I have extended the user model to add some additional information. Users can register via django-allauth (google OAuth2) fine, and entries are added to their database.
class LabUser(models.Model):
user = models.OneToOneField(User)
verified = models.BooleanField(default=False, blank=False)
phone_number = models.CharField(max_length=30, verbose_name="Phone Number", null=True, blank=True)
home_phone = models.CharField(max_length=30,verbose_name="Home Phone", null=True, blank=True)
def __unicode__(self):
return self.user.username
However, when I try to add another user using the django-admin panel, I get the following database error:
IntegrityError: duplicate key value violates unique constraint "lab_manager_labuser_user_id_key"
DETAIL: Key (user_id)=(24) already exists.
After examining the tables in psql I see the following:
l=# select id, username from auth_user;
id | username
----+----------------
13 | xxxx
23 | xxxx
18 | xxxx
12 | xxxx
21 | xxxx
14 | xxxx
22 | xxxx
1 | xxxx
(8 rows)
l=# select id, user_id from lab_manager_labuser;
id | user_id
----+---------
9 | 13
1 | 1
16 | 18
8 | 12
10 | 14
21 | 21
22 | 22
23 | 23
(8 rows)
looking at my sequence tables I can see that the values are higher than in their respective model tables:
l=# SELECT sequence_name, last_value FROM auth_user_id_seq;
sequence_name | last_value
------------------+------------
auth_user_id_seq | 24
(1 row)
l=# SELECT sequence_name, last_value FROM lab_manager_labuser_id_seq;
sequence_name | last_value
----------------------------+------------
lab_manager_labuser_id_seq | 25
(1 row)
I have looked at this similar question, but cannot find a reason why this collision should be happening in my case. Both of the sequences appear to be ahead of the values in my table.
i.e. I have tried the following, and while it increments my key, it still causes supposed integrity errors, while these keys clearly do not exist in the database.
SELECT setval('lab_manager_labuser_id_seq', (SELECT MAX(user_id) from lab_manager_labuser)+1)")
Any help would be appreciated.
Update:
I set up a receiver to create a labuser model as follows, maybe I am doing this incorrectly which is causing database mismatches:
@receiver(post_save, sender=User)
def add_labuser(sender, created, instance, **kwargs):
if created:
LabUser.objects.create(user=instance)
I think this must be part of the problem, as I can create the user object successfully with the following code in shell:
a = User()
##(add fields)##
a.save()
LabUser.objects.create(user=a)
The reason the duplicate key error is occurring is because I am adding the users through the admin panel with an inline as such:
class LabUserInline(admin.StackedInline):
model = LabUser
can_delete = False
Apparently when the user is created through Admin, a LabUser record is automatically created through the inline, before save is called. Then when the post_save signal is received, django tries to create another LabUser record for the same User object, upon which the key collision occurs.
Would anyone know how to circumvent this redundancy?
lab_manager_labuseris inserted twice, which causes this problem. No entry withuser_id=24makes me think that you're using transactions and on error everything is rolled back.