简体   繁体   中英

django.db.utils.IntegrityError: NOT NULL constraint failed: BookApp_book.publisher_id while updating models with fake data

I am trying to populate my models using some fake data generated through faker in my django project. I have created three models Publisher, Author, and Book. The migrations are done correctly and the models are created successfully. I am able to add the data to the models through admin interface, but when i try to populate the models through fake data i am getting the following error. django.db.utils.IntegrityError: NOT NULL constraint failed: BookApp_book.publisher_id I am not able to figure out what is the mistake. Here is my 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')

Error Trace back

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

Look at your error trace, it tells you exactly where the error is happening and what it is:

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

You're trying to create a book without pages and without publisher here. NOT NULL constraint failed means you're assign None to fields that should not be None .

I don't understand why you do that in add_title() since you should return a string, not a Book object (later on you assign it as title to create the Book ).

You have a pages = models.PositiveSmallIntegerField() field in your model that doesnt have a default or null parameter.

You should either add a default

pages = models.PositiveSmallIntegerField(default=123)

or allow it to be null

pages = models.PositiveSmallIntegerField(null=True)

Don't forget to perform a migration after changing models!

Also, it seems like you aren't putting any values into the field upon fake data creation.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM