You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter使用sqflite存储数据报错,请求协助排查解决

问题排查与解决

错误原因分析

1. 参数类型不支持错误

sqflite仅支持num、String、Uint8List类型的字段值,你传入的是嵌套的_InternalLinkedHashMap(每个recipeID对应一个包含名称和分类的Map),不符合sqflite的字段类型要求。

2. SQL语法错误

你将整个recipeMap传给了insert方法,这个Map的键是Firestore中的recipeID(如101、102),sqflite错误地把这些键当成了数据库表的列名。但你的表结构里根本没有这些数字列名,同时SQL中列名不能以纯数字开头,直接导致语法报错。

修复步骤

1. 修改数据传递逻辑

不要把所有Recipe打包成一个嵌套Map,而是遍历每个Recipe,生成对应表结构的扁平Map,逐个插入数据库:

修改getRecipeData方法:

Future<void> getRecipeData() async {
  recipes = await RecipeModel().getRecipeDataList();
  count = await RecipeModel().getRecipeCount();

  final dbHelper = DatabaseHelper();
  // 逐个处理每个Recipe
  for (int i = 0; i < count; i++) {
    final recipe = recipes[i];
    // 生成符合表结构的扁平Map
    final recipeData = {
      'recipeId': recipe.recipeID,
      'recipeName': recipe.recipeName,
      'recipe_category': recipe.recipeCategory,
      'synced': 0 // 默认未同步,可根据需求调整
    };
    // 逐个插入数据库
    await dbHelper.saveRecipe(recipeData);
  }
}

2. 增强数据库方法健壮性(可选)

你的saveRecipe方法已适配单条Recipe的插入需求,可添加空值判断避免字段缺失:

Future<int> saveRecipe(Map<String, dynamic> recipe) async {
  var dbClient = await db;
  // 可选:添加必填字段校验
  assert(recipe.containsKey('recipeId'), 'recipeId 为必填字段');
  assert(recipe.containsKey('recipeName'), 'recipeName 为必填字段');
  assert(recipe.containsKey('recipe_category'), 'recipe_category 为必填字段');
  
  int res = await dbClient!.insert(recipeTable, recipe);
  return res;
}

修复效果验证

修改后两个错误都会被解决:

  • 传入的是符合表结构的扁平Map,不再有嵌套Map类型,解决参数类型不兼容问题;
  • insert语句会使用正确的列名(recipeId、recipeName等),不再出现数字列名,解决SQL语法错误。

内容的提问来源于stack exchange,提问作者Ahmed Raza

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 21:33:22