Flutter Sqflite数据库NOT NULL约束失败问题求助
问题描述
我跟着YouTube教程开发Flutter数据库应用,严格遵循所有步骤,但点击保存按钮添加新笔记时,持续抛出SqfliteDatabaseException错误:NOT NULL constraint failed: Note.Text (code 1299 SQLITE_CONSTRAINT_NOTNULL)。错误截图如下:
相关代码文件如下:
note_model.dart
class Note { final int? id; final String title; final String content; const Note({required this.title, required this.content, this.id}); factory Note.fromJson(Map<String, dynamic> json) => Note( id: json['id'], title: json['title'], content: json['content'], ); Map<String, dynamic> toJson() => { 'id': id, 'title': title, 'content': content, }; @override String toString() { return "id: $id title: $title content: $content "; } }
database_helper.dart
import 'package:dummy_database/models/note_model.dart'; import 'package:sqflite/sqflite.dart'; import 'package:path/path.dart'; class DatabaseHelper { static const int _version = 1; static const String _dbName = "Notes.db"; static Future<Database> _getDB() async { return openDatabase(join(await getDatabasesPath(), _dbName), onCreate: (db, version) async => await db.execute( "CREATE TABLE Note(id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT NOT NULL, content TEXT NOT NULL);"), version: _version); } static Future<int> addNote(Note note) async { final db = await _getDB(); return await db.insert("Note", note.toJson(), conflictAlgorithm: ConflictAlgorithm.replace); } static Future<int> updateNote(Note note) async { final db = await _getDB(); return await db.update("Note", note.toJson(), where: 'id = ?', whereArgs: [note.id], conflictAlgorithm: ConflictAlgorithm.replace); } static Future<int> deleteNote(Note note) async { final db = await _getDB(); return await db.delete( "Note", where: 'id = ?', whereArgs: [note.id], ); } static Future<List<Note>?> getAllNotes() async { final db = await _getDB(); final List<Map<String, dynamic>> maps = await db.query("Note"); if (maps.isEmpty) { return null; } return List.generate(maps.length, (index) => Note.fromJson(maps[index])); } }
引发异常的文件(NoteScreen.dart)
import 'dart:developer'; import 'package:dummy_database/models/note_model.dart'; import 'package:dummy_database/services/database_helper.dart'; import 'package:flutter/material.dart'; class NoteScreen extends StatelessWidget { final Note? note; NoteScreen({Key? key, this.note}) : super(key: key); final titleController = TextEditingController(); final contentController = TextEditingController(); @override Widget build(BuildContext context) { if (note != null) { titleController.text = note!.title; contentController.text = note!.content; } return Scaffold( appBar: AppBar( title: Text(note == null ? 'Add a note' : 'Edit note'), centerTitle: true, ), body: Padding( padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 30), child: Column( children: [ const Padding( padding: EdgeInsets.only(bottom: 40), child: Center( child: Text( 'What are you thinking about?', style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold), ), ), ), Padding( padding: const EdgeInsets.only(bottom: 40.0), child: TextFormField( controller: titleController, maxLines: 1, decoration: const InputDecoration( hintText: 'Title', labelText: 'Note title', border: OutlineInputBorder( borderSide: BorderSide( color: Colors.white, width: 0.75, ), borderRadius: BorderRadius.all( Radius.circular(10.0), ))), ), ), TextFormField( controller: contentController, decoration: const InputDecoration( hintText: 'Type here the note', labelText: 'Note content', border: OutlineInputBorder( borderSide: BorderSide( color: Colors.white, width: 0.75, ), borderRadius: BorderRadius.all( Radius.circular(10.0), ))), keyboardType: TextInputType.multiline, onChanged: (str) {}, maxLines: 5, ), const Spacer(), Padding( padding: const EdgeInsets.only(bottom: 20.0), child: SizedBox( height: 45, width: MediaQuery.of(context).size.width, child: ElevatedButton( onPressed: () async { final title = titleController.value.text; final content = contentController.value.text; log("title value is $title, content value is $content"); if (title.isEmpty || content.isEmpty) { return; } final Note model = Note(title: title, content: content, id: note?.id); log(model.toString()); if (note == null) { await DatabaseHelper.addNote(model); } else { await DatabaseHelper.updateNote(model); } Navigator.pop(context); }, style: ButtonStyle( shape: MaterialStateProperty.all( const RoundedRectangleBorder( side: BorderSide( color: Colors.white, width: 0.75, ), borderRadius: BorderRadius.all( Radius.circular(10.0), )))), child: Text( note == null ? 'Save' : 'Edit', style: const TextStyle(fontSize: 20), )), ), ) ], ), ), ); } }
解决方案
错误提示里的Note.Text字段在你当前的表结构中根本不存在(你现在的表只有title和content字段),这说明设备上的数据库是旧版本——你之前可能创建过包含Text字段的表,后来修改了建表语句,但sqflite只会在数据库首次创建时执行onCreate方法,旧数据库不会自动更新结构。
解决方法很简单:
- 直接卸载设备上的应用,然后重新运行项目,这样会创建全新的数据库,使用你当前的表结构。
- 如果你不想卸载应用,可以在
DatabaseHelper中实现onUpgrade方法来迁移数据库,但开发阶段卸载重建是最快捷的方式。
另外可以确认你的代码逻辑:NoteScreen中已经做了非空判断(title.isEmpty || content.isEmpty时直接返回),所以不会出现空值插入的情况,核心问题就是旧数据库结构不匹配。
内容的提问来源于stack exchange,提问作者Omer Elkhalifa
相关产品推荐
相关产品推荐

