导入CSV至SQLite的drilling表后页面加载报错:invalid literal for int() with base 10
解决Django外键导入CSV后触发的
ValueError: invalid literal for int() with base 10问题 问题根源
你遇到的错误本质很清晰:Django的外键字段在SQLite数据库中是以xxx_id命名的整数类型字段,存储的是关联模型的主键ID(比如project_name_id存的是Project表中对应记录的整数ID)。但你导入CSV时,把关联对象的名称/编码字符串(比如'B-A-BRS01',应该是Project模型的某个业务字段值)直接写入了这个整数字段,导致Django渲染模板时,尝试把这个字符串转成整数来关联Project实例,最终触发类型转换错误。
解决方案
根据你的场景,有三种可行的修复方式,你可以根据数据量和操作习惯选择:
1. 手动修正CSV后重新导入(适合小数据量)
这是最直接的方式:
- 先在DB Browser for SQLite中查询所有关联模型的主键ID和业务字段的映射关系,比如查询
Project表:SELECT id, project_code FROM your_app_project; -- 替换成你的实际表名和存'B-A-BRS01'的业务字段 - 把CSV中所有外键列的值,替换成对应的整数ID:比如把CSV里
project_name列的'B-A-BRS01'改成查询到的对应ID(比如1) - 清空
drilling表中已导入的错误数据,重新用DB Browser导入修正后的CSV
2. 用Python脚本批量导入(推荐,适合大数据量)
写一个Django自定义管理命令,自动通过CSV中的业务字段找到关联模型实例,再创建Drilling对象,避免手动映射ID:
- 在你的Django应用下创建
management/commands目录(如果没有的话),新建import_drilling.py文件:import csv from django.core.management.base import BaseCommand from your_app.models import Drilling, Project, Personel, Auger, Client, Vehicle class Command(BaseCommand): help = 'Imports drilling data from CSV' def handle(self, *args, **kwargs): # 替换成你的CSV文件实际路径 csv_path = '/path/to/your/drilling_data.csv' with open(csv_path, 'r', encoding='utf-8') as f: reader = csv.DictReader(f) for row_num, row in enumerate(reader, 1): try: # 根据CSV中的业务字段找到关联模型实例,替换成你实际的字段名 project = Project.objects.get(project_code=row['project_name']) geologist = Personel.objects.get(personel_full_name=row['geologist']) driller = Personel.objects.get(personel_full_name=row['driller']) auger = Auger.objects.get(auger_model=row['auger']) client = Client.objects.get(client_name=row['client']) vehicle = Vehicle.objects.get(vehicle_plate=row['vehicle']) # 创建Drilling记录 Drilling.objects.create( project_name=project, drill_date=row['drill_date'], shift=row['shift'], holes_drilled=row['holes_drilled'], meters_drilled=row['meters_drilled'], avgdepth_drilled=row['avgdepth_drilled'], targetmeters_drilled=row['targetmeters_drilled'], comment=row['comment'], geologist=geologist, driller=driller, auger=auger, client=client, vehicle=vehicle ) except Exception as e: self.stdout.write(self.style.ERROR(f"Row {row_num} failed: {str(e)}")) self.stdout.write(self.style.SUCCESS('Drilling data import completed')) - 运行命令导入数据:
python manage.py import_drilling
3. 直接修正已导入的错误数据
如果已经导入了错误数据,不想重新导入,可以直接在SQLite中执行UPDATE语句修正:
比如修正project_name_id字段:
UPDATE your_app_drilling SET project_name_id = (SELECT id FROM your_app_project WHERE project_code = 'B-A-BRS01') WHERE project_name_id = 'B-A-BRS01';
同理,对geologist_id、driller_id等其他外键字段执行类似的UPDATE语句,替换对应的表名、字段名和业务值。
注意事项
- 导入前必须确保所有关联模型(
Project、Personel等)的对应记录已经存在于数据库中,否则会触发DoesNotExist错误 - 用DB Browser导入CSV时,一定要注意外键列对应的是数据库中的
xxx_id整数字段,必须填入整数ID而非业务字符串
内容的提问来源于stack exchange,提问作者vially
相关产品推荐
相关产品推荐

