SQLite无法自动分配ID 插入问题数据时survey_id非空约束报错如何解决
问题原因
sqlalchemy.exc.IntegrityError: (sqlite3.IntegrityError) NOT NULL constraint failed: questions.survey_id
该报错核心是插入Questions表数据时,外键字段survey_id未赋值触发非空约束。手动给Survey分配ID可正常运行,是因为明确指定了关联的survey_id值,不需要等待数据库生成自增ID。
自动处理实现方案
无需手动分配Survey ID,按以下流程操作即可让SQLAlchemy自动处理关联逻辑:
- 第一步:先创建Survey实例,提交到数据库事务生成自增ID
# 示例代码 new_survey = Survey() db.session.add(new_survey) # flush会将数据提交到数据库临时事务生成ID,后续操作失败可回滚不污染正式数据 db.session.flush() # 执行完flush后,new_survey.id已经获取到数据库自动生成的自增ID
- 第二步:创建Questions实例时关联Survey,两种方式二选一即可:
- 直接给survey_id字段赋值:
new_question = Questions( survey_id = new_survey.id, lan_code = 'en', q1 = 'how are you?', q2 = 'Did you get vaccinated?', q3 = 'When is your birthday?' )- 通过已定义的relationship属性关联:
new_question = Questions( lan_code = 'en', q1 = 'how are you?', q2 = 'Did you get vaccinated?', q3 = 'When is your birthday?' ) new_survey.question_ts.append(new_question) - 第三步:提交所有改动到数据库
db.session.add(new_question) db.session.commit()
可选优化
如果想进一步简化操作,可以给relationship配置cascade参数,实现自动关联保存子对象:
修改Survey类的relationship定义:
question_ts = db.relationship('Questions', cascade="all, delete-orphan")
配置后无需单独add Questions实例,只要把Questions实例添加到survey的question_ts列表中,commit时会自动保存数据并填充survey_id:
# 简化后流程 new_survey = Survey() new_question = Questions( lan_code = 'en', q1 = 'how are you?', q2 = 'Did you get vaccinated?', q3 = 'When is your birthday?' ) new_survey.question_ts.append(new_question) db.session.add(new_survey) db.session.commit()
内容的提问来源于stack exchange,提问作者Egzon Korenica
相关产品推荐
相关产品推荐

