[英]IntegrityError Primary Key Invalid in django
在 model 的訂單 Class 中修復了一些問題。 然后,我運行遷移。 但是,它顯示為錯誤
django.db.utils.IntegrityError:表“core_order”中主鍵為“4”的行具有無效的外鍵:core_order.billing_address_id 包含一個在core_address.id 中沒有對應值的>值“1”。
模型.py
from django.conf import settings
from django.db import models
from django.db.models import Sum
from django.shortcuts import reverse
from django_countries.fields import CountryField
# Create your models here.
CATEGORY_CHOICES = (
('SB', 'Shirts And Blouses'),
('TS', 'T-Shirts'),
('SK', 'Skirts'),
('HS', 'Hoodies&Sweatshirts')
)
LABEL_CHOICES = (
('S', 'sale'),
('N', 'new'),
('P', 'promotion')
)
class Item(models.Model):
title = models.CharField(max_length=100)
price = models.FloatField()
discount_price = models.FloatField(blank=True, null=True)
category = models.CharField(choices=CATEGORY_CHOICES, max_length=2)
label = models.CharField(choices=LABEL_CHOICES, max_length=1)
slug = models.SlugField()
description = models.TextField()
image = models.ImageField()
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse("core:product", kwargs={
'slug': self.slug
})
def get_add_to_cart_url(self):
return reverse("core:add-to-cart", kwargs={
'slug': self.slug
})
def get_remove_from_cart_url(self):
return reverse("core:remove-from-cart", kwargs={
'slug': self.slug
})
class OrderItem(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL,
on_delete=models.CASCADE)
ordered = models.BooleanField(default=False)
item = models.ForeignKey(Item, on_delete=models.CASCADE)
quantity = models.IntegerField(default=1)
def __str__(self):
return f"{self.quantity} of {self.item.title}"
def get_total_item_price(self):
return self.quantity * self.item.price
def get_total_discount_item_price(self):
return self.quantity * self.item.discount_price
def get_amount_saved(self):
return self.get_total_item_price() - self.get_total_discount_item_price()
def get_final_price(self):
if self.item.discount_price:
return self.get_total_discount_item_price()
return self.get_total_item_price()
class Order(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL,
on_delete=models.CASCADE)
ref_code = models.CharField(max_length=20)
items = models.ManyToManyField(OrderItem)
start_date = models.DateTimeField(auto_now_add=True)
ordered_date = models.DateTimeField()
ordered = models.BooleanField(default=False)
billing_address = models.ForeignKey(
'BillingAddress', on_delete=models.SET_NULL, blank=True, null=True)
payment = models.ForeignKey(
'Payment', on_delete=models.SET_NULL, blank=True, null=True)
coupon = models.ForeignKey(
'Coupon', on_delete=models.SET_NULL, blank=True, null=True)
being_delivered = models.BooleanField(default=False)
received = models.BooleanField(default=False)
refund_requested = models.BooleanField(default=False)
refund_granted = models.BooleanField(default=False)
'''
1. Item added to cart
2. Adding a BillingAddress
(Failed Checkout)
3. Payment
4. Being delivered
5. Received
6. Refunds
'''
def __str__(self):
return self.user.username
def get_total(self):
total = 0
for order_item in self.items.all():
total += order_item.get_final_price()
if self.coupon:
total -= self.coupon.amount
return total
class BillingAddress(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL,
on_delete=models.CASCADE)
street_address = models.CharField(max_length=100)
apartment_address = models.CharField(max_length=100)
country = CountryField(multiple=False)
zip = models.CharField(max_length=100)
def __str__(self):
return self.user.username
class Payment(models.Model):
stripe_charge_id = models.CharField(max_length=50)
user = models.ForeignKey(settings.AUTH_USER_MODEL,
on_delete=models.SET_NULL, blank=True, null=True)
amount = models.FloatField()
timestamp = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.user.username
class Coupon(models.Model):
code = models.CharField(max_length=15)
amount = models.FloatField()
def __str__(self):
return self.code
class Refund(models.Model):
order = models.ForeignKey(Order, on_delete=models.CASCADE)
reason = models.TextField()
accepted = models.BooleanField(default=False)
email = models.EmailField()
def __str__(self):
return f"{self.pk}"
我撤消到以前的代碼,但是當我遷移時仍然顯示主鍵錯誤
刪除了除__init__.py
文件之外的所有遷移記錄。
還刪除了db.sqlite3文件。
然后,運行以下命令
python manage.py makemigrations core
python manage.py migrate
希望這個幫助
例如,給定一個 orders 表和一個 customers 表,如果您創建一個列orders.customer_id
引用customers.id
主鍵:
在orders.customer_id
中插入或更新的每個值都必須與customers.id
中的值完全匹配,或者是 NULL。
除非您有級聯操作,否則無法刪除或更新orders.customer_id
引用的customers.id
中的值。 但是,可以刪除或更新orders.customer_id
中不存在的customers.id
值。
如果您在遷移中犯了錯誤,最簡單的撤消方法是向后遷移。 例如,如果您剛剛創建了 0003 遷移:
manage.py migrate your_app 0002
rm your_app/migrations/0003_*.py
如果出現錯誤,您還可以更改遷移的 state 而無需實際運行它們:
manage.py migrate --fake your_app 0002
手動修復數據庫
rm your_app/migrations/0003_*.py
我們可以在 sqlite 上解決此問題的另一種方法是:
要刪除地址表,您必須:
打開 sqlite.exe 程序將打開一個 dbshell 終端,您可以通過以下命令看到那里的所有表和架構:
.databases ( shows all the databases)
.schema *
“.schema”命令顯示所有附加數據庫的模式。 如果您只想查看單個數據庫(可能是“主”)的架構,那么您可以向“.schema”添加一個參數以限制其 output:
.schema main.*
現在您可以看到數據庫和數據庫索引出現問題。 現在您需要: 禁用外鍵約束。 刪除地址表。 將 people 表中的 address_id 更新為 NULL 值。 啟用外鍵約束。
PRAGMA foreign_keys = OFF;
DROP TABLE addresses;
UPDATE people
SET address_id = NULL;
PRAGMA foreign_keys = ON;
在上面的示例中,您可以假設有兩個表 People 和 Addresses。 人員表使用地址 ID 作為地址中的外鍵。 由於foreign_key 約束,我們無法刪除該表或無法修改該表。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.