迁移由原来的用户模型数据定义用户模型在Django 1.8(Migrate data from or

2019-10-24 00:49发布

我创建了一个自定义的用户模型。 目前已经有在身份验证数据库用户。 所以,我使用的数据迁移到数据迁移到我的自定义用户模型。

这是我怎么没在自动迁移文件中的数据迁移(这是我从发现这里 ):

更新

from __future__ import unicode_literals

from django.db import models, migrations


class Migration(migrations.Migration):

    dependencies = [
        ('userauth', '0002_auto_20150721_0605'),
    ]

    operations = [
        migrations.RunSQL('INSERT INTO userauth_userauth SELECT * FROM auth_user'),
        migrations.RunSQL('INSERT INTO userauth_userauth_groups SELECT * FROM auth_user_groups'),
        migrations.RunSQL('INSERT INTO userauth_userauth_user_permissions SELECT * FROM auth_user_user_permissions'),
    ]

models.py

class UserManager(BaseUserManager):
        def _create_user(self, username, email, password, is_staff, is_superuser, **extra_fields):
            now = timezone.now()
            if not username:
              raise ValueError(_('The given username must be 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 and @/./+/-/_ characters'),
        validators=[
          validators.RegexValidator(re.compile('^[\w.@+-]+$'), _('Enter a 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 the user can log into this admin site.'))
        is_active = models.BooleanField(_('active'), default=False,
        help_text=_('Designates whether this user should be treated as active. Unselect this 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 your 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])

迁移后的问题,我无法创建新用户。 我得到这个错误:

重复键值违反唯一约束“userauth_userauth_pkey”详细信息:按键(ID)=(3)已经存在。

似乎该表是不同步的。 我该如何解决?

Answer 1:

在Postgres的,Django的处理其数据库记录创造独特的主键的方法是使用一个数据库序列从中获得新的主键。 展望在我自己的数据库中,我看到,如果我有一个表命名为x,则Django的创建名称X下的序列_id_seq 。 因此,对于你的序列userauth_userauth表将userauth_userauth_id_seq

现在,你做你的迁移方式,你去与原始的SQL语句。 这完全绕过Django的ORM,这意味着新表序列没有被迁移感动。 什么执行这样的原迁移后,你应该做的是主键序列设置为一个数字,不会有什么已经是在数据库中发生冲突。 从借用这个答案 ,那么你应该发出:

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

并执行同类的其他表操作:设置自己的序列,如果他们的最大值id字段。 (如果你想知道,将通过获得将使用的下一个值nextval和将等于一个比前序列的值更nextval被调用。)

在评论你想知道为什么创建新用户最终会奏效。 可能发生的事情是,你试图创建新用户,它是这样的:

  1. Django中得到了适当的序列的新的主键。 这里的顺序被递增。

  2. Django的试图挽救新用户,这失败,因为它在上一步得到的数量不是唯一的。

如果你这样做足够的时间,你的程序将获得递增的每一个尝试,因为不论交易 ,Postgres没有回滚序列。 该文件说:

重要的是:由于序列的非事务性的,通过由变化setval如果事务回滚不是撤消。

所以最终,该序列增加过去在表中的最大主已经键,并从该点起,它的工作原理。



Answer 2:

您正在使用什么数据库? 这听起来像你的数据库具有既然你创建了主键的新行时,产生像3. ID的主键的计数器,你可能需要手动复位DB计数器。 对于Postgres的示例,请参阅如何重置时,它属于不同步的Postgres的主键序列?



文章来源: Migrate data from original User model to Custom User model in django 1.8