对于包含地图的地图,SQFLite(颤振)插入失败

时间:2020-03-03 06:40:56

标签: flutter dart sqflite

有人可以确认SQFLite是否支持包含地图的地图?我确实在此站点上遇到了以下帖子,可能是答案?

Flutter sqflite insert List<String>

在我的情况下,我有两个正在使用的模型类。

  • 房屋

房屋中有一个名为pets的字段,它是一个列表

在每个此类中我都有一个构造函数和factory方法,该方法负责根据需要向SQFLite发送信息和从SQFLite检索信息所需的映射/对象转换。

模型类 狗

class Dog {
  final int id;
  final String breed;
  final String name;
  final int age;

  Dog({this.id, this.breed, this.name, this.age});

  // Used when inserting a row into the db, including the id field
  Map<String, dynamic> toMap() {
    final map = Map<String, dynamic>();
    map['id'] = id;
    map['breed'] = breed;
    map['name'] = name;
    map['age'] = age;
    return map;
  }

  // Used when returning a row from the DB and converting into an object
  factory Dog.fromMap(Map<String, dynamic> data) => Dog(
      id: data['id'],
      breed: data['breed'],
      name: data['name'],
      age: data['age']
  );
}

房屋

import 'dog.dart';

class House{
  final int id;
  final String name;
  final String color;
  final List<Dog> pets;

  House({this.id, this.name, this.color, this.pets});

  // Will be used when inserting a row into the database
  Map<String, dynamic> toMap() {
    final map = Map<String, dynamic>();
    map['id'] = id;
    map['name'] = name;
    map['color'] = color;
    if (this.pets != null) {
      map['pets'] = this.pets.map((pet) => pet.toMap()).toList();
    }
    return map;
  }

  // Used when returning a row from the DB and converting into an object
  factory House.fromMap(Map<String, dynamic> data) {
    return House(
      id: data['id'],
      name: data['name'],
      color: data['color'],
      pets: data['pets'] != null
          ? (data['pets'] as List).map((pet) => Dog.fromMap(pet)).toList()
          : null,
    );
  }
}

插入新房子的方法

Future<int> addNewHome(House house) async {
    // Attempt to add the house to the DB
    var client = await database.db;
    int result = await client.insert(HomesSchema.tblHomes, house.toMap(), conflictAlgorithm: ConflictAlgorithm.replace);
    _homes.add(house);
    return result;
  }

当我尝试执行插入操作时,出现以下错误。

E/flutter (  586): [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: DatabaseException(java.util.HashMap cannot be cast to java.lang.Integer) sql 'INSERT OR REPLACE  INTO homes (id, name, color, pets) VALUES (?, ?, ?, ?)' args [1, Smith, Green, [{name: Mackie, id: 1, breed: Rottweiler, age: 8}, {name: Tanner, id: 2, breed: Mastiff, age: 8}]]}
E/flutter (  586): #0      wrapDatabaseException (package:sqflite/src/exception_impl.dart:12:7)
E/flutter (  586): <asynchronous suspension>
E/flutter (  586): #1      SqfliteDatabaseFactoryImpl.wrapDatabaseException (package:sqflite/src/factory_impl.dart:25:7)
E/flutter (  586): #2      SqfliteDatabaseMixin.safeInvokeMethod (package:sqflite/src/database_mixin.dart:188:15)
E/flutter (  586): #3      SqfliteDatabaseMixin.txnRawInsert.<anonymous closure> (package:sqflite/src/database_mixin.dart:363:14)
E/flutter (  586): #4      SqfliteDatabaseMixin.txnSynchronized.<anonymous closure> (package:sqflite/src/database_mixin.dart:307:22)
E/flutter (  586): #5      BasicLock.synchronized (package:synchronized/src/basic_lock.dart:32:26)
E/flutter (  586): #6      SqfliteDatabaseMixin.txnSynchronized (package:sqflite/src/database_mixin.dart:303:43)
E/flutter (  586): #7      SqfliteDatabaseMixin.txnWriteSynchronized (package:sqflite/src/database_mixin.dart:325:7)
E/flutter (  586): #8      SqfliteDatabaseMixin.txnRawInsert (package:sqflite/src/database_mixin.dart:362:12)
E/flutter (  586): #9      SqfliteDatabaseExecutorMixin.rawInsert (package:sqflite/src/database_mixin.dart:49:15)
E/flutter (  586): #10     SqfliteDatabaseExecutorMixin.insert (package:sqflite/src/database_mixin.dart:59:12)
E/flutter (  586): #11     Homes.addNewHome (package:search_list_view/providers/homes.dart:19:31)
E/flutter (  586): <asynchronous suspension>
E/flutter (  586): #12     _MyAppState.build.<anonymous closure> (package:search_list_view/main.dart:95:26)
E/flutter (  586): #13     _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:706:14)
E/flutter (  586): #14     _InkResponseState.build.<anonymous closure> (package:flutter/src/material/ink_well.dart:789:36)
E/flutter (  586): #15     GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:182:24)
E/flutter (  586): #16     TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:486:11)
E/flutter (  586): #17     BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:264:5)
E/flutter (  586): #18     BaseTapGestureRecognizer.handlePrimaryPointer (package:flutter/src/gestures/tap.dart:199:7)
E/flutter (  586): #19     PrimaryPointerGestureRecognizer.handleEvent (package:flutter/src/gestures/recognizer.dart:467:9)
E/flutter (  586): #20     PointerRouter._dispatch (package:flutter/src/gestures/pointer_router.dart:76:12)
E/flutter (  586): #21     PointerRouter._dispatchEventToRoutes.<anonymous closure> (package:flutter/src/gestures/pointer_router.dart:117:9)
E/flutter (  586): #22     _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:379:8)
E/flutter (  586): #23     PointerRouter._dispatchEventToRoutes (package:flutter/src/gestures/pointer_router.dart:115:18)
E/flutter (  586): #24     PointerRouter.route (package:flutter/src/gestures/pointer_router.dart:101:7)
E/flutter (  586): #25     GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:218:19)
E/flutter (  586): #26     GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:198:22)
E/flutter (  586): #27     GestureBinding._handlePointerEvent (package:flutter/src/gestures/binding.dart:156:7)
E/flutter (  586): #28     GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:102:7)
E/flutter (  586): #29     GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:86:7)
E/flutter (  586): #30     _rootRunUnary (dart:async/zone.dart:1138:13)
E/flutter (  586): #31     _CustomZone.runUnary (dart:async/zone.dart:1031:19)
E/flutter (  586): #32     _CustomZone.runUnaryGuarded (dart:async/zone.dart:933:7)
E/flutter (  586): #33     _invoke1 (dart:ui/hooks.dart:273:10)
E/flutter (  586): #34     _dispatchPointerDataPacket (dart:ui/hooks.dart:182:5)
E/flutter (  586): 

如果答案是更改我的数据库架构,那么我有一个将狗和房子连接起来的表,然后执行自定义查询以拉回我所需要的信息,那么就可以了。看来nosql db应该能够处理这个问题似乎不是太过分了。是/否?

任何帮助将不胜感激。

谢谢, 鲍勃

2 个答案:

答案 0 :(得分:1)

要在SQLite数据库中存储任何类型的值,您只需将对象序列化为JSON字符串,然后反序列化该对象即可。 假设您有一个名为Menu的类。 (我在这里使用可序列化的JSON)

   class Menu {

   @JsonKey(name: "status")
   String status;
   @JsonKey(name: "data")
   MenuListData menuListData;

   Menu(this.status, this.menuListData);
   factory Menu.fromJson(Map<String,dynamic> 
   json)=>_$MenuFromJson(json);
   Map<String, dynamic> toJson() => _$MenuToJson(this);

 }

这是在JSON中进行编码并将其存储在您的集团中的方法。

   Menue menuList =
    await getIt<LiveMenuRepository>().getMenuResponse(menuPost);

    //decode the response to String format
    String menuResponseString = jsonEncode(menuList);

    //convert the string to Map of <String,dynamic> format

    Map<String, dynamic> menuResponseMap = {"menu": menuResponseString};

    //store this Map response in to local database
    int menuStored = await getIt<LocalMenuRepository>().insertMenuResponseData(menuResponseMap);

您的数据库插入方法

Future<int> insertMenuResponseData(Map<String,dynamic> menuResponse) async {
final db = await dbProvider.database;
var result = db.insert(menuTable, menuResponse);
return result;
}

稍后使用

检索对象
final Map<String, dynamic> menuList = await getIt<LocalMenuRepository>().getMenuResponseString();
  //  if(menuList!=null) {
      menuList.forEach((key, value) {
        if (key == "menu") {
          storedMenu = value ;
        }
      });
      //decode the string back to Map Object
      final dynamic menuMap = jsonDecode(storedMenu);

      //getting the Menu object using fromJson method

      final Menu menuListNameResponse = Menu
          .fromJson(menuMap as Map<String,dynamic>);
db中的

// getMenuResponseString方法

Future<Map<String,dynamic>> getMenuResponse() async {
final db = await dbProvider.database;

List<Map<String, dynamic>> result;

result = await db.rawQuery('SELECT * FROM $menuTable');
// print(result[0]);

if (result.length > 0) {

  return result[0];
}
return null;
}

答案 1 :(得分:0)

此处列出了受支持的类型(num,String或Uint8List):https://github.com/tekartik/sqflite/blob/master/sqflite/doc/supported_types.md

不支持嵌套内容,“地图”和“列表”应以受支持的类型编码,例如作为json字符串。