Python django.db.utils.IntegrityError:非空约束失败:unesco\u site.category\u id
我正在尝试使用python脚本从csv文件中的数据填充数据库。我做了一些研究,但没有找到相关的示例,而是找到了可以加载csv的python包。还有一些文章指导如何上传csv文件,这不是我想要的 以下是对该文件的简要介绍。如您所见,共有11列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
# 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
。在那之后,一切顺利。再次感谢。