【问题标题】:django.db.utils.IntegrityError: NOT NULL constraint failed: unesco_site.category_iddjango.db.utils.IntegrityError:NOT NULL 约束失败:unesco_site.category_id
【发布时间】:2020-09-08 03:57:30
【问题描述】:

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

以下是load.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_or_create() 方法,但建议不要使用它,因为我没有defaultvalue 可以给出并使用create() 方法。我在某个地方发现,在保存数据之前,不会生成主键,因此我每次在读取数据后都尝试将数据保存到字段中,但这也不起作用。 .以下是 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= 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

【问题讨论】:

  • 您应该从阅读.create() 方法的文档开始。这是一个原子操作;您不能像上面那样一一添加字段。同样创建一个Site() 对象然后save()ing 它与.create() 基本相同。你应该选择一个。
  • 谢谢@Selcuk 我也做了同样的事情,现在一切正常。谢谢你的时间。拯救了我的一天。

标签: python django django-models django-rest-framework django-views


【解决方案1】:

发生此错误是因为您将字符串值传递给Sitecategory 字段,但它需要Category 对象,因为它是ForeignKey 字段。

不光是你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()

【讨论】:

  • 非常感谢。你拯救了我的一天。实际上,在那之后,我也不得不在野外区域做一些改变。我不得不更改为CharField。我还必须在models.py 中进行另一次更正。我应该在 Category 和 State 类中做 return self.category'return self.state。之后,一切正常。再次感谢。
猜你喜欢
  • 2020-06-08
  • 2020-07-04
  • 2018-12-24
  • 2021-05-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-23
相关资源
最近更新 更多