django .db.utils.IntegrityError: Сбой ограничения NOT NULL: BookApp_book.publisher_id при обновлении моделей с поддельными данными - PullRequest
0 голосов
/ 24 февраля 2020

Я пытаюсь заполнить мои модели, используя некоторые поддельные данные, сгенерированные через фейкер в моем проекте django. Я создал три модели Publisher, Author и Book. Миграции выполнены правильно, а модели созданы успешно. Я могу добавить данные в модели через интерфейс администратора, но когда я пытаюсь заполнить модели ложными данными, я получаю следующую ошибку: django .db.utils.IntegrityError: Сбой ограничения NOT NULL: BookApp_book.publisher_id Я не могу понять, в чем ошибка. Вот мой models.py

from django.db import models

# Create your models here.

class Publisher(models.Model):

    '''
    Publisher class model with name,country,email,website
    '''
    name = models.CharField(max_length=25)
    country = models.CharField(max_length=25)
    website = models.URLField()

    def __str__(self):
        return self.name


class Author(models.Model):
    '''
    Author model with name,contact,email,age,location
    '''
    author_name = models.CharField(max_length=25)
    age = models.PositiveSmallIntegerField()
    email = models.EmailField()

    # method for string representation of the class
    def __str__(self):
        return self.author_name

class Book(models.Model):
    '''
    Book model with title,pages,author,publisher,publication_date
    '''
    title = models.CharField(max_length=100)
    pages = models.PositiveSmallIntegerField()
    author = models.ManyToManyField('Author')
    publisher = models.ForeignKey(Publisher,related_name='publisher',on_delete=models.CASCADE)
    publication_date = models.DateField()

    # method for string representation of book class
    def __str__(self):
        return self.title

populate_bookapp.py

import os
# set the default environment to the projects settings
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'BooksProject.settings')

import django
django.setup()

# faker popscript to populate the models with fake data
from faker import Faker
from BookApp.models import Publisher,Author,Book
import random

# create an object for faker
fake_gen = Faker()

titlelist = ['Impossible Spindle','Savage Vice','Shackle the future','Eden Grieving',
            'Cloaked Grace','Crime of the Silent Baker','The Sulphur Earth',
            'Snows of Jupiter','The Demon in the Window','Tapped for Duty']

# function to add the book titles
def add_title():
    t = Book.objects.get_or_create(title = random.choice(titlelist))[0]
    t.save()
    return t

# function to populate the records into the models
def populate_records(N=5):

    # for loop to generate the data
    for entry in range(N):

        # create fake names, urls, emails, companies, books, dates
        fake_auth_name = fake_gen.name()
        fake_country = fake_gen.country()
        fake_website = fake_gen.url()
        fake_comp = fake_gen.company()
        fake_age = fake_gen.random_int(0,60)
        fake_email = fake_gen.email()
        fake_pages = fake_gen.random_int(0,500)
        fake_date = fake_gen.date()

        # add a publisher entry
        pub = Publisher.objects.get_or_create(name=fake_comp,
                                            country=fake_country,
                                            website=fake_website)[0]

        # add a author entry
        auth = Author.objects.get_or_create(author_name=fake_auth_name,
                                            age=fake_age,
                                            email=fake_email)[0]

        book_title = add_title()
        # add book entry
        bk_rec = Book.objects.get_or_create(title=book_title,
                                            pages=fake_pages,author=auth,
                                            publisher=pub,
                                            publication_date=fake_date)[0]

# Add records to the models
if __name__ == '__main__':
    print('Populating started')
    populate_records(10)
    print('Finished')

Ошибка трассировки

Populating started
Traceback (most recent call last):
File "C:\Users\Gururaj Deshpande\Anaconda3\envs\MyDjangoEnv\lib\site-                        
 packages\django\db\models\query.py", line 538, in get_or_create
return self.get(**kwargs), False
  File "C:\Users\Gururaj Deshpande\Anaconda3\envs\MyDjangoEnv\lib\site-        
 packages\django\db\models\query.py", line 406, in get
raise self.model.DoesNotExist(
BookApp.models.DoesNotExist: Book matching query does not exist.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "C:\Users\Gururaj Deshpande\Anaconda3\envs\MyDjangoEnv\lib\site- 
packages\django\db\backends\utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
File "C:\Users\Gururaj Deshpande\Anaconda3\envs\MyDjangoEnv\lib\site- 
packages\django\db\backends\sqlite3\base.py", line 383, in execute
return Database.Cursor.execute(self, query, params)
sqlite3.IntegrityError: NOT NULL constraint failed: BookApp_book.pages

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
File "populate_bookapp.py", line 62, in <module>
populate_records(10)
File "populate_bookapp.py", line 52, in populate_records
book_title = add_title()
File "populate_bookapp.py", line 22, in add_title
t = Book.objects.get_or_create(title = random.choice(titlelist))[0]
File "C:\Users\Gururaj Deshpande\Anaconda3\envs\MyDjangoEnv\lib\site- 
packages\django\db\models\manager.py", line 82, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "C:\Users\Gururaj Deshpande\Anaconda3\envs\MyDjangoEnv\lib\site- 
packages\django\db\models\query.py", line 541, in get_or_create
return self._create_object_from_params(kwargs, params)
File "C:\Users\Gururaj Deshpande\Anaconda3\envs\MyDjangoEnv\lib\site- 
packages\django\db\models\query.py", line 583, in _create_object_from_params
raise e
File "C:\Users\Gururaj Deshpande\Anaconda3\envs\MyDjangoEnv\lib\site- 
packages\django\db\models\query.py", line 575, in _create_object_from_params
obj = self.create(**params)
File "C:\Users\Gururaj Deshpande\Anaconda3\envs\MyDjangoEnv\lib\site- 
packages\django\db\models\query.py", line 422, in create
obj.save(force_insert=True, using=self.db)
File "C:\Users\Gururaj Deshpande\Anaconda3\envs\MyDjangoEnv\lib\site- 
packages\django\db\models\base.py", line 740, in save
self.save_base(using=using, force_insert=force_insert,
File "C:\Users\Gururaj Deshpande\Anaconda3\envs\MyDjangoEnv\lib\site- 
packages\django\db\models\base.py", line 777, in save_base
updated = self._save_table(
File "C:\Users\Gururaj Deshpande\Anaconda3\envs\MyDjangoEnv\lib\site- 
packages\django\db\models\base.py", line 870, in _save_table
result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
File "C:\Users\Gururaj Deshpande\Anaconda3\envs\MyDjangoEnv\lib\site- 
packages\django\db\models\base.py", line 907, in _do_insert
return manager._insert([self], fields=fields, return_id=update_pk,
File "C:\Users\Gururaj Deshpande\Anaconda3\envs\MyDjangoEnv\lib\site- 
packages\django\db\models\manager.py", line 82, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "C:\Users\Gururaj Deshpande\Anaconda3\envs\MyDjangoEnv\lib\site- 
packages\django\db\models\query.py", line 1186, in _insert
return query.get_compiler(using=using).execute_sql(return_id)
File "C:\Users\Gururaj Deshpande\Anaconda3\envs\MyDjangoEnv\lib\site-p 
ackages\django\db\models\sql\compiler.py", line 1335, in execute_sql
cursor.execute(sql, params)
File "C:\Users\Gururaj Deshpande\Anaconda3\envs\MyDjangoEnv\lib\site- 
packages\django\db\backends\utils.py", line 99, in execute
return super().execute(sql, params)
 File "C:\Users\Gururaj Deshpande\Anaconda3\envs\MyDjangoEnv\lib\site- 
packages\django\db\backends\utils.py", line 67, in execute
return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
File "C:\Users\Gururaj Deshpande\Anaconda3\envs\MyDjangoEnv\lib\site- 
packages\django\db\backends\utils.py", line 76, in _execute_with_wrappers
return executor(sql, params, many, context)
File "C:\Users\Gururaj Deshpande\Anaconda3\envs\MyDjangoEnv\lib\site- 
packages\django\db\backends\utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
File "C:\Users\Gururaj Deshpande\Anaconda3\envs\MyDjangoEnv\lib\site-packages\django\db\utils.py", 
line 89, in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
File "C:\Users\Gururaj Deshpande\Anaconda3\envs\MyDjangoEnv\lib\site- 
packages\django\db\backends\utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
File "C:\Users\Gururaj Deshpande\Anaconda3\envs\MyDjangoEnv\lib\site- 
packages\django\db\backends\sqlite3\base.py", line 383, in execute
return Database.Cursor.execute(self, query, params)
django.db.utils.IntegrityError: NOT NULL constraint failed: BookApp_book.pages

Ответы [ 2 ]

0 голосов
/ 24 февраля 2020

В вашей модели есть поле pages = models.PositiveSmallIntegerField(), в котором нет параметра default или null.

Вы должны либо добавить значение по умолчанию

pages = models.PositiveSmallIntegerField(default=123)

или оставьте значение NULL

pages = models.PositiveSmallIntegerField(null=True)

Не забудьте выполнить миграцию после смены модели!

Кроме того, похоже, что вы не ' t помещать любые значения в поле при создании поддельных данных.

0 голосов
/ 24 февраля 2020

Посмотрите на свою трассировку ошибок, она точно скажет вам, где произошла ошибка и что это такое:

File "populate_bookapp.py", line 22, in add_title
t = Book.objects.get_or_create(title = random.choice(titlelist))[0]

Вы пытаетесь создать книгу без pages и без publisher здесь , NOT NULL constraint failed означает, что вы присваиваете None полям, которые не должны быть None.

Я не понимаю, почему вы делаете это в add_title(), поскольку вы должны возвращать строку, а не Book объект (позже вы назначите его как title для создания Book).

...