django.db.utils.IntegrityError not solving this part

310 Views Asked by At

I need a help regarding django.db.utils.IntegrityError: I read similar questions on Stack Overflow before posting a new question, but I could not find the right solution.

Basically, I am following a course, let's say copy-pasting the code in models.py, serializers.py views.py And whenever I call python manage.py migrate, I get this error:

django.db.utils.IntegrityError: The row in table 'LittleLemonAPI_menuitem' with primary key '1' has an invalid foreign key: LittleLemonAPI_menuitem.category_id contains a value '1' that does not have a corresponding value in LittleLemonAPI_category.id.

Anyone can help, how could I fix that error? The strange part is, that I literally follow each step on the course, it isn't even my code, and I can't figure out what's wrong.

I tried to delete all migration related files and db.sqlite3, but in that way I lose all the previously entered data.

I tried changing the part from on_delete.PROTECT, default=1. into on_delete.CASCADE and removing default1, but nothing worked.

3

There are 3 best solutions below

0
sergenp On

It's basically complaining about not finding a "LittleLemonAPI_category" with id of "1" here:

'1' that does not have a corresponding value in LittleLemonAPI_category.id.

You need to insert a category with the id of 1 before inserting your menuitem

1
Shohan On

The easiest way to solve this error, Comment out the Category class and Foreign Key from MenuItem class like this: example with image

from django.db import models

#class Category(models.Model):
#   slug = models.SlugField()
#   title = models.CharField(max_length=255)

class MenuItem(models.Model):
    title = models.CharField(max_length=255)
    price = models.DecimalField(max_digits=6, decimal_places=2)
    inventory = models.SmallIntegerField()
    # category = models.ForeignKey(Category, on_delete=models.PROTECT, default=1)

Then remove the 'category' from serializers field. After that, run the server and go to the single menu item from your browser. You can find your single item like that: http://127.0.0.1:8000/api/menu-items/2

Delete these items one by one and then remove the class comment, migrate and run again your server. Hope it will work.

0
unknown On

I will do my best to describe how I got this to work.

NOTE: I took a backup of my project before getting stuck at the relationship serializers module. By doing so I was able to export my previous data from the database file which I later imported into a new database (see step 4 below).

  1. Delete the Database File: I deleted the db.sqlite3 file, which is the SQLite database for my Django project. This effectively removes all the data and schema for my project.

  2. Delete Migrations: I navigated into the migrations directory of each Django app in my project and deleted all files there, except for the __init__.py file. This removes all migration history for my project.

  3. Flush and Migrate: I ran the following commands in the terminal:

    • python manage.py flush: This command removes all data from the database and resets the database to its initial state. Since I had already deleted the db.sqlite3 file, this command was more of a safety measure to ensure the database was completely reset.

    • python manage.py migrate: This command applies all migrations (which are now only the initial migrations provided by Django for its built-in apps, since I deleted all custom migrations in step 2). This effectively creates a new, empty database for my project.

  4. Using the database table/file from before I updated my code (following the instructor) and eventually got stuck at the error described above this post, I exported the LittleLemonAPI.menuitem table into .json file:

    • python manage.py dumpdata LittleLemonAPI.menuitem > data.json

NOTE: So as to not get confused, the project backup can be named whatever you like. What's important is that you have access to the old database file and it's situated in the same directory as the manage.py file, else the above command won't work.

Again, please make sure this step is done in a different folder from your current project directory where you have the new, empty database file. Otherwise you won't get any data running the export command.

Below is the content of the data.json file:

[
    {
        "model": "LittleLemonAPI.menuitem", 
        "pk": 1, 
        "fields": {
            "title": "Chocolate Cake", 
            "price": "2.50", 
            "inventory": 100,
            "category_id": 1
        }
    }, 
    {
        "model": "LittleLemonAPI.menuitem", 
        "pk": 2, 
        "fields": {
            "title": "Vanilla Ice Cream", 
            "price": "1.50", 
            "inventory": 100,
            "category_id": 1
        }
    }, 
    {
        "model": "LittleLemonAPI.menuitem", 
        "pk": 3, 
        "fields": {
            "title": "Strawberry Ice Cream", 
            "price": "1.50", 
            "inventory": 100,
            "category_id": 1
        }
    }
]

  1. I downloaded and installed sqlite3 so I could tinker with the database. I pretty much followed the steps in this YouTube video. After setting up the environment variables in Windows, I had to restart my VS Code for the changes to reflect in the terminal.

  2. Now, after step 3, you basically have an empty database file. I navigated to the directory of my project where the new, empty database file (db.sqlite3) is and ran the following:

    sqlite3 db.sqlite3

This gave me access to the database. So, I ran the following commands to create tables and fill them with data:

  • Create a table for Menu Item:
CREATE TABLE IF NOT EXISTS "LittleLemonAPI_menuitem" (
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
"title" varchar(255) NOT NULL,
"price" decimal NOT NULL,
"inventory" smallint NOT NULL,
"category_id" integer NOT NULL DEFAULT 1
);
  • Insert Data from the exported data.json file:
INSERT INTO "LittleLemonAPI_menuitem" ("id", "title", "price", "inventory", "category_id")
VALUES (1, 'Chocolate Cake', 2.50, 100, 1),(2, 'Vanilla Ice Cream', 1.50, 100, 1),(3, 'Strawberry Ice Cream', 1.50, 100, 1);
  • Create a table for category:
CREATE TABLE LittleLemonAPI_category (
"id" INTEGER PRIMARY KEY AUTOINCREMENT, 
"slug" varchar(255) NOT NULL, 
"title" varchar(255) NOT NULL
);

I go on to quit out of sqlit3 by running: .quit.

  1. I configured admin.py so I could have access to the admin page:
from django.contrib import admin
from .models import Category, MenuItem

admin.site.register(Category)
admin.site.register(MenuItem)

Then I go on to create a superuser:

python manage.py createsuperuser

This command will prompt you to enter a username, email address, and password for the superuser. The superuser will have full access to the Django admin site.

You should also run the makemigrations and migrate commands:

  • python manage.py makemigrations
  • python manage.py migrate

Then start the server:

  • python manage.py runserver
  1. Navigate to http://localhost:8000/admin, log in with the superuser credentials, and you should be able to see Categorys and Menu Items in the left panel.

You can select either to view and/or edit the content.

Select Categorys > ADD CATEGORY and fill out whatever you like in the slug and title fields.

You can create as many categories as you like.

Go on to save that.

Then try to access http://localhost:8000/api/menu-items

--

Do excuse the formatting - pretty new here.

--

This might also be helpful