Flask中用Peewee插入数据报错:NOT NULL constraint failed: Time.start
错误原因分析
- 字段非空约束触发:
Time模型里的start是IntegerField,Peewee默认所有字段null=False(不允许为空),但你的插入逻辑两次违反这个规则:- 第一个循环遍历
Drivers插入Time时,只传了name参数,完全未赋值start,直接触发NOT NULL约束错误。 - 第二个循环遍历
start列表插入Time时,只传了start参数,未传外键name,同样会触发外键字段的非空约束。
- 第一个循环遍历
- 外键赋值错误:
Time的name是关联Drivers的外键,必须传入Drivers的实例对象,你传的name.name是字符串类型的车手姓名,会导致外键关联失败。 - 数据类型不匹配:
start.log里的时间是字符串格式(如2018-05-24 12:02:58.917),但Time.start定义为IntegerField,直接插入字符串会引发类型错误,需先转换为整数格式(比如时间戳)。
修正后的插入脚本
from reports.report import parse_racer_team, read_file from models import Drivers, Time, db from datetime import datetime DATA = 'data/' def insert_drivers_data(path): drivers = parse_racer_team(path) start_log = read_file(path + 'start.log') # 批量插入车手数据 for code, name in drivers.items(): Drivers(code=code, name=name).save() # 关联车手与起始时间,插入完整Time记录 for code, start_time_str in start_log: # 通过车手code找到对应的Drivers实例 driver = Drivers.get(Drivers.code == code) # 将时间字符串转为毫秒级时间戳整数 start_timestamp = int(datetime.strptime(start_time_str, "%Y-%m-%d %H:%M:%S.%f").timestamp() * 1000) # 插入符合约束的Time数据 Time(name=driver, start=start_timestamp).save() # 创建表时添加safe=True,避免表已存在时报错 Drivers.create_table(safe=True) Time.create_table(safe=True) insert_drivers_data(DATA)
额外提示
- 若需要秒级时间戳,去掉转换代码里的
* 1000即可。 - 若
parse_racer_team返回的是{code: name}结构的字典,for code, name in drivers.items()的写法比item[0]/item[1]更直观。
内容的提问来源于stack exchange,提问作者DmitryTok
相关产品推荐
相关产品推荐

