首页 > 解决方案 > “django.db.utils.ProgrammingError: 列 Staff.id 不存在 LINE 1: SELECT "Staff"."id", "Staff"."user_id", "Staff"."department"...."

问题描述

我创建了一个自定义用户模型,并有两个模型“员工”和“患者”与我的自定义用户模型具有 OneToOne 关系。我已成功迁移,但执行第二行代码时出现错误

doc = User.objects.create_user(email='jlennon@beatles.com',password='glassdoor',user_type=1)
s_doc = Staff.objects.get_or_create(user=doc)

,我得到这个错误:“django.db.utils.ProgrammingError: 列 Staff.id 不存在 LINE 1: SELECT "Staff"."id", "Staff"."user_id", "Staff"."department"。 ..”

模型.py

class User(AbstractUser):

    #use email as authentication
    username = None
    email = models.EmailField(_('email address'), unique=True)

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = []

    objects = CustomUserManager()

    USER_TYPE_CHOICES = (
      (1, 'doctor'),
      (2, 'labPeople'),
      (3, 'receptionist'),
      (4, 'patient'),
      (5, 'admin'),
    )
    user_type = models.PositiveSmallIntegerField(choices=USER_TYPE_CHOICES,null=True)

    def __str__(self):
        return self.email
  # class Meta:
  #       db_table = 'auth_user'

class Staff(models.Model):
    user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE,related_name='staff')
    id = models.AutoField(db_column='ID', primary_key=True)  # Field name made lowercase.
    fname = models.CharField(max_length=255, blank=True, null=True)
    lname = models.CharField(max_length=255, blank=True, null=True)
    sex = models.BooleanField(blank=True, null=True)
    tel_no = models.CharField(max_length=255, blank=True, null=True)
    email = models.EmailField(max_length=255,unique=True)
    department = models.ForeignKey('Department', on_delete=models.CASCADE, db_column='department', blank=True, null=True)
    hospital = models.ForeignKey('Hospital', on_delete=models.CASCADE, db_column='hospital', blank=True, null=True)

    class Meta:
        # managed = False
        db_table = 'Staff'

class Patient(models.Model):
    user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE,related_name='patient')
    email = models.EmailField(max_length=255,unique=True)
    fname = models.CharField(max_length=255, blank=True, null=True)
    lname = models.CharField(max_length=255, blank=True, null=True)
    dob = models.DateField(db_column='DOB', blank=True, null=True)  # Field name made lowercase.
    sex = models.BooleanField(blank=True, null=True)
    tel_no = models.CharField(max_length=255,blank=True,null=True)
    address = models.CharField(max_length=255, blank=True, null=True)
    nin = models.AutoField(db_column='NIN', primary_key=True)  # Field name made lowercase.

    class Meta:
        # managed = False
        db_table = 'Patient'

管理者.py

from django.contrib.auth.base_user import BaseUserManager
from django.utils.translation import ugettext_lazy as _
from django.db import models
import django



class CustomUserManager(BaseUserManager):
    """
    Custom user model manager where email is the unique identifiers
    for authentication instead of usernames.
    """
    use_in_migrations = True
    def _create_user(self, email, user_type, password, **extra_fields):
        """
        Create and save a User with the given email and password.
        """
        django.setup()
        if not email:
            raise ValueError('The Email must be set')
        email = self.normalize_email(email)
        user = self.model(email=email, user_type=user_type, **extra_fields)
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_user(self, email, user_type, password=None, **extra_fields):
        """Create and save a regular User with the given email and password."""
        extra_fields.setdefault('is_staff', False)
        extra_fields.setdefault('is_superuser', False)
        if user_type in set([1,2,3,5]):
            is_staff = True
        return self._create_user(email, user_type, password, **extra_fields)

    def create_superuser(self, email, user_type, password, **extra_fields):
        """
        Create and save a SuperUser with the given email and password.
        """
        extra_fields.setdefault('is_staff', True)
        extra_fields.setdefault('is_superuser', True)
        extra_fields.setdefault('is_active', True)

        if extra_fields.get('is_staff') is not True:
            raise ValueError('Superuser must have is_staff=True.')
        if extra_fields.get('is_superuser') is not True:
            raise ValueError('Superuser must have is_superuser=True.')
        return self._create_user(email, user_type, password, **extra_fields)

Traceback 如下:

Traceback (most recent call last):
  File "populate_health.py", line 90, in <module>
    populate()
  File "populate_health.py", line 26, in populate
    s_doc = Staff.objects.get_or_create(user=doc)
  File "//anaconda/envs/myhealth/lib/python3.7/site-packages/django/db/models/manager.py", line 82, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "//anaconda/envs/myhealth/lib/python3.7/site-packages/django/db/models/query.py", line 538, in get_or_create
    return self.get(**kwargs), False
  File "//anaconda/envs/myhealth/lib/python3.7/site-packages/django/db/models/query.py", line 402, in get
    num = len(clone)
  File "//anaconda/envs/myhealth/lib/python3.7/site-packages/django/db/models/query.py", line 256, in __len__
    self._fetch_all()
  File "//anaconda/envs/myhealth/lib/python3.7/site-packages/django/db/models/query.py", line 1242, in _fetch_all
    self._result_cache = list(self._iterable_class(self))
  File "//anaconda/envs/myhealth/lib/python3.7/site-packages/django/db/models/query.py", line 55, in __iter__
    results = compiler.execute_sql(chunked_fetch=self.chunked_fetch, chunk_size=self.chunk_size)
  File "//anaconda/envs/myhealth/lib/python3.7/site-packages/django/db/models/sql/compiler.py", line 1100, in execute_sql
    cursor.execute(sql, params)
  File "//anaconda/envs/myhealth/lib/python3.7/site-packages/django/db/backends/utils.py", line 99, in execute
    return super().execute(sql, params)
  File "//anaconda/envs/myhealth/lib/python3.7/site-packages/django/db/backends/utils.py", line 67, in execute
    return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
  File "//anaconda/envs/myhealth/lib/python3.7/site-packages/django/db/backends/utils.py", line 76, in _execute_with_wrappers
    return executor(sql, params, many, context)
  File "//anaconda/envs/myhealth/lib/python3.7/site-packages/django/db/backends/utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)
  File "//anaconda/envs/myhealth/lib/python3.7/site-packages/django/db/utils.py", line 89, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "//anaconda/envs/myhealth/lib/python3.7/site-packages/django/db/backends/utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)
django.db.utils.ProgrammingError: column Staff.id does not exist
LINE 1: SELECT "Staff"."id", "Staff"."user_id", "Staff"."department"...

当我没有为 Staff 定义 id 时,我第一次遇到这个错误,因为 django 只是自动执行它。但是我只是添加它来尝试,结果是一样的。我也尝试创建一个 Patient 对象,它会导致同样的错误。

我已经坚持了一个多星期,只发现迁移时发生了一些其他类似的问题,这是不一样的。这是怎么回事?

标签: djangopopulate

解决方案


容易这个错误是由于具有多个“id”值而被购买的,因为您的表中有一个主键,并且 django 还为您的“id”提供了一个自动值。使用“DROP [IF] 删除当前数据库存在]数据库名;" 然后使用相同的名称再次创建数据库,然后使用“python manage.py makemigrations”再次进行迁移,然后使用“python manage.py migrate”进行迁移,它会正常工作。


推荐阅读