database migration - Migrate data from original User model to Custom User model in django 1.8 -


i created custom user model. there have users in auth database. so, using data migration migrate data custom user model.

this how did data migration in auto migration file (which found here):

updated

from __future__ import unicode_literals  django.db import models, migrations   class migration(migrations.migration):      dependencies = [         ('userauth', '0002_auto_20150721_0605'),     ]      operations = [         migrations.runsql('insert userauth_userauth select * auth_user'),         migrations.runsql('insert userauth_userauth_groups select * auth_user_groups'),         migrations.runsql('insert userauth_userauth_user_permissions select * auth_user_user_permissions'),     ] 

models.py

class usermanager(baseusermanager):         def _create_user(self, username, email, password, is_staff, is_superuser, **extra_fields):             = timezone.now()             if not username:               raise valueerror(_('the given username must set'))             email = self.normalize_email(email)             user = self.model(username=username, email=email,                      is_staff=is_staff, is_active=false,                      is_superuser=is_superuser, last_login=now,                      date_joined=now, **extra_fields)             user.set_password(password)             user.save(using=self._db)             if not is_staff:                 group = group.objects.get(name='normal')                 user.groups.add(group)             return user          def create_user(self, username, email=none, password=none, **extra_fields):             return self._create_user(username, email, password, false, false,                      **extra_fields)          def create_superuser(self, username, email, password, **extra_fields):             user=self._create_user(username, email, password, true, true,                          **extra_fields)             user.is_active=true             user.save(using=self._db)             return user       class userauth(abstractbaseuser, permissionsmixin):         #original fields         username = models.charfield(_('username'), max_length=30, unique=true,         help_text=_('required. 30 characters or fewer. letters, numbers , @/./+/-/_ characters'),         validators=[           validators.regexvalidator(re.compile('^[\w.@+-]+$'), _('enter valid username.'), _('invalid'))         ])         first_name = models.charfield(_('first name'), max_length=30, blank=true, null=true)         last_name = models.charfield(_('last name'), max_length=30, blank=true, null=true)         email = models.emailfield(_('email address'), max_length=255, unique=true)         is_staff = models.booleanfield(_('staff status'), default=false,         help_text=_('designates whether user can log admin site.'))         is_active = models.booleanfield(_('active'), default=false,         help_text=_('designates whether user should treated active. unselect instead of deleting accounts.'))         date_joined = models.datetimefield(_('date joined'), default=timezone.now)       #additional fields         full_name =  models.charfield(_('full name'), max_length=600, blank=true, null=true)         profileimage = models.imagefield(upload_to="upload",blank=true,null=true,         help_text = _("please upload picture"))         biouser =  models.textfield(blank=true,null=true)         social_link = models.urlfield(blank=true,null=true)          objects = usermanager()         username_field = 'username'         required_fields = []          class meta:             verbose_name = _('user')             verbose_name_plural = _('users')          def get_full_name(self):             return self.full_name          def get_short_name(self):             return self.first_name          def email_user(self, subject, message, from_email=none):             send_mail(subject, message, from_email, [self.email]) 

the problem after migration, can't create new user. error:

duplicate key value violates unique constraint "userauth_userauth_pkey" detail: key (id)=(3) exists.

seem table out of sync. how fix this?

on postgres, way django handles creating unique primary keys database records using database sequence gets new primary keys. looking in own database, see if have table named x, django creates sequence under name x_id_seq. sequence userauth_userauth table userauth_userauth_id_seq.

now, way did migration went raw sql statements. bypasses django's orm, means sequences new tables not touched migration. should after performing such raw migration set primary key sequence number won't clash in database. borrowing this answer, should issue:

select setval('userauth_userauth_id_seq', max(id))         userauth_userauth; 

and perform same kind of operation other tables: set own sequences max value if id field. (if wonder, next value used obtained through nextval , equal 1 more value of sequence before nextval called.)

in comment wondered why creating new users worked. happened trying create new users , went this:

  1. django got new primary key appropriate sequence. here sequence gets incremented.

  2. django tried save new user, failed because number got in previous step not unique.

if enough times, sequence incremented each try because irrespective of transactions, postgres not rollback sequences. documentation says:

important: because sequences non-transactional, changes made setval not undone if transaction rolls back.

so eventually, sequence increases past maximum primary key in table, , point onwards works.


Comments