Python django.db.utils.IntegrityError:非空约束失败:unesco\u site.category\u id

Python django.db.utils.IntegrityError:非空约束失败:unesco\u site.category\u id,python,django,django-models,django-rest-framework,django-views,Python,Django,Django Models,Django Rest Framework,Django Views,我正在尝试使用python脚本从csv文件中的数据填充数据库。我做了一些研究,但没有找到相关的示例,而是找到了可以加载csv的python包。还有一些文章指导如何上传csv文件,这不是我想要的 以下是对该文件的简要介绍。如您所见,共有11列 # models.py from django.db import models class Category(models.Model): category = models.CharField(max_length=128) def

我正在尝试使用python脚本从csv文件中的数据填充数据库。我做了一些研究,但没有找到相关的示例,而是找到了可以加载csv的python包。还有一些文章指导如何上传csv文件,这不是我想要的

以下是对该文件的简要介绍。如您所见,共有11列

# models.py
from django.db import models


class Category(models.Model):
    category = models.CharField(max_length=128)

    def __str__(self):
        return self.name

class State(models.Model):
    state = models.CharField(max_length=25)

    def __str__(self):
        return self.name


class Region(models.Model):
    region = models.CharField(max_length=25)

    def __str__(self):
        return self.region

class Iso(models.Model):
    iso = models.CharField(max_length=5)

    def __str__(self):
        return self.iso

class Site(models.Model):
    name = models.CharField(max_length=128)
    year = models.IntegerField(null=True)
    area = models.FloatField(null=True)
    describe = models.TextField(max_length=500)
    justify = models.TextField(max_length=500, null=True)
    longitude = models.TextField(max_length=25, null=True)
    latitude = models.TextField(max_length=25, null=True)

    #one to many field
    category = models.ForeignKey(Category, on_delete=models.CASCADE)
    state = models.ForeignKey(State, on_delete=models.CASCADE)
    region = models.ForeignKey(Region, on_delete=models.CASCADE)
    iso = models.ForeignKey(Iso, on_delete=models.CASCADE)

    def __str__(self):
        return self.name
我无法在插入数据时建立模型之间的关系。早些时候,我使用了
get\u或\u create()
方法,但建议我不要使用它,因为我没有要给定和使用的
create()
方法的
default
值。在某个地方,我发现,在保存数据之前,主键不会生成,所以每次读取数据后,我都会尝试将数据保存到字段中,但这也不起作用。以下是许多_load.py脚本中的代码。读取数据没有问题

import csv 

#python3 manage.py runscript many_load

from unesco.models import Site, Category, Iso, Region, State

def run():
    fhand = open('unesco/load.csv')
    reader = csv.reader(fhand)
    next(reader)

    
    # Category.objects.all().delete()
    # Iso.objects.all().delete()
    # Region.objects.all().delete()
    # State.objects.all().delete()

    # Site.objects.all().delete()


    for row in reader:
        # print(row)
        # print (len(row))

        nm= Site.objects.create(name=row[0])
        dsc = Site.objects.create(describe=row[1])
        jst = Site.objects.create(justify=row[2])
        yr = Site.objects.create(year=row[3])
        lng = Site.objects.create(longitude=row[4])
        lat = Site.objects.create(latitude=row[5])
        area = Site.objects.create(area=row[6])

        
        st = Site(category=row[7], state=row[8], region=row[9], iso=row[10], 
                    name=nm, area=area, describe=dsc, justify=jst, longitude=lng, latitude=lat)
        st.save()
但是,当我尝试运行脚本
python3 manage.py runscript many_load
时,会出现以下错误。请帮忙。你也可以参考一些好的文章,让我更了解这一点

Traceback (most recent call last):
  File "/home/bu113t/envs/djpro/lib/python3.8/site-packages/django/db/backends/utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)
  File "/home/bu113t/envs/djpro/lib/python3.8/site-packages/django/db/backends/sqlite3/base.py", line 413, in execute
    return Database.Cursor.execute(self, query, params)
sqlite3.IntegrityError: NOT NULL constraint failed: unesco_site.category_id

发生此错误的原因是,您正在将字符串值传递给
站点
类别
字段,但它需要一个
类别
对象,因为它是一个
外键
字段

不仅如此,您在
many_load.py中还有其他问题

以下代码更正了所有问题。希望它对你有用

import csv

# python3 manage.py runscript many_load

from unesco.models import Site, Category, Iso, Region, State


def run():
    fhand = open('unesco/load.csv')
    reader = csv.reader(fhand)
    next(reader)

    # Category.objects.all().delete()
    # Iso.objects.all().delete()
    # Region.objects.all().delete()
    # State.objects.all().delete()

    # Site.objects.all().delete()

    for row in reader:
        # print(row)
        # print (len(row))

        nm = row[0]
        dsc = row[1]
        jst = row[2]
        yr = row[3]
        lng = row[4]
        lat = row[5]
        area = row[6]

        category = Category.objects.create(category=row[7])
        state = State.objects.create(state=row[8])
        region = Region.objects.create(region=row[9])
        iso = Iso.objects.create(iso=row[10])

        st = Site(category=category, state=state, region=region, iso=iso,
                  name=nm, area=area, describe=dsc, justify=jst, longitude=lng, latitude=lat)
        st.save()

您应该先阅读
.create()
方法的文档。这是一个原子操作;不能像上面那样逐个添加字段。另外,创建一个
Site()
对象,然后
save()
ing它与
.create()
基本相同。你应该选一个。谢谢@Selcuk我也这么做了,现在一切都正常了。谢谢你抽出时间。救了我一天,非常感谢。你救了我一天。事实上,在那之后,我也不得不在场地上做一些改变。我不得不换成
CharField
。我还必须在
models.py
中进行另一次更正。我应该在category和state类中执行
返回self.category'
返回self.state
。在那之后,一切顺利。再次感谢。