Flutter Sqflite错误说,对空调用了“查询”方法

时间:2019-01-13 10:48:11

标签: dart flutter

我正在尝试从网络中获取一些数据并将其存储在sqlite数据库中。以下是模型类

class StudentModel {
  int status;
  String msg;
  StudentModelData studentModelData;

  StudentModel({this.status, this.msg, this.studentModelData});

  StudentModel.fromJson(Map<String, dynamic> json) {
    status = json['status'];
    msg = json['msg'];
    studentModelData = json['data'] != null ? new StudentModelData.fromJson(json['data']) : null;
  }

  StudentModel.fromDb(Map<String, dynamic> parsedJson) {
    status = parsedJson['status'];
    msg = parsedJson['msg'];
    studentModelData = studentModelData = jsonDecode(json['data']) != null ? new StudentModelData.fromJson(jsonDecode(json['data'])) : null;
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['status'] = this.status;
    data['msg'] = this.msg;
    if (this.studentModelData != null) {
      data['data'] = this.studentModelData.toJson();
    }
    return data;
  }
}

class StudentModelData {
  int lastIndex;
  List<StudentData> studentData;

  StudentModelData({this.lastIndex, this.studentData});

  StudentModelData.fromJson(Map<String, dynamic> json) {
    lastIndex = json['lastIndex'];
    if (json['studentData'] != null) {
      studentData = new List<StudentData>();
      json['studentData'].forEach((v) {
        studentData.add(new StudentData.fromJson(v));
      });
    }
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['lastIndex'] = this.lastIndex;
    if (this.studentData != null) {
      data['studentData'] = this.studentData.map((v) => v.toJson()).toList();
    }
    return data;
  }
}

class StudentData {
  String studentId;
  String studName;
  String studProfilepic;
  String studentEmail;
  String studentMobile;
  String courseName;
  String classCode;
  int minAvg;
  int avg;

  StudentData(
      {this.studentId,
        this.studName,
        this.studProfilepic,
        this.studentEmail,
        this.studentMobile,
        this.courseName,
        this.classCode,
        this.minAvg,
        this.avg});

  StudentData.fromJson(Map<String, dynamic> json) {
    studentId = json['student_id'];
    studName = json['stud_name'];
    studProfilepic = json['stud_profilepic'];
    studentEmail = json['student_email'];
    studentMobile = json['student_mobile'];
    courseName = json['course_name'];
    classCode = json['class_code'];
    minAvg = json['minAvg'];
    avg = json['avg'];
  }



  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['student_id'] = this.studentId;
    data['stud_name'] = this.studName;
    data['stud_profilepic'] = this.studProfilepic;
    data['student_email'] = this.studentEmail;
    data['student_mobile'] = this.studentMobile;
    data['course_name'] = this.courseName;
    data['class_code'] = this.classCode;
    data['minAvg'] = this.minAvg;
    data['avg'] = this.avg;
    return data;
  }
}

我的数据库提供程序类如下所示

class StudentDbProvider implements Source, Cache {
  Database db;

  StudentDbProvider() {
    init();
  }

  void init() async {
    Directory documentsDirectory = await getApplicationDocumentsDirectory();
    final path = join(documentsDirectory.path, "students.db");
    db = await openDatabase(path, version: 1,
        onCreate: (Database newDb, int version) {

        newDb.execute("""
          CREATE TABLE STUDENTS(
            id INTEGER PRIMARY KEY,
            status INTEGER,
            msg TEXT,
            data BLOB
          )
        """);
    });
  }

  @override
  Future<int> clear() {
    return db.delete("STUDENTS");
  }

  @override
  Future<StudentModel> fetchStudents(String disciplineId, String schoolId,
      String year_id, String lastIndex) async {

    final maps =
        await db.query("STUDENTS");

    if (maps.length > 0) {
      return StudentModel.fromDb(maps.first);
    }

    return null;
  }

  @override
  Future<int> addStudent(StudentModel studentModel) {

    return db.insert("STUDENTS", studentModel.toJson(),conflictAlgorithm: ConflictAlgorithm.ignore);
  }

}

final studentDbProvider = StudentDbProvider();

每当我尝试获取数据并将其存储在数据库中时,在控制台中都会出现以下错误

NoSuchMethodError: The method 'query' was called on null.
Receiver: null
Tried calling: query("STUDENTS")
#0      Object.noSuchMethod (dart:core/runtime/libobject_patch.dart:50:5)

数据已添加到数据库,但是我无法从数据库中查询数据。

2 个答案:

答案 0 :(得分:1)

至少减少您的示例,这将引发异常The method 'query' was called on null 因为fetch是在db正确初始化之前执行的:

class Database {

  Future<int> query() {
    return Future.value(1);
  }
}

const oneSecond = Duration(seconds: 1);

class Provider {

  Database db;

  Provider() {
    init();
  }

  void init() async {
    db = await Future.delayed(oneSecond, () => Database());
  }

  Future<int> fetch() {
    return db.query();
  }

}

main() async {
  var provider = Provider();
  await provider.fetch();
}

问题出在构造函数内部调用异步方法,另请参见:

这有效:

class Database {

  Future<int> query() {
    return Future.value(1);
  }

}

const oneSecond = Duration(seconds: 1);

class Provider {

  Database db;

  Provider() {
    //init();
  }

  void init() async {
    db = await Future.delayed(oneSecond, () => Database());
  }

  Future<int> fetch() {
    return db.query();
  }

}

main() async {
  var provider = Provider();
  await provider.init();

  await provider.fetch();
}

请注意,必须等待init,否则您将遇到相同的The method 'query' was called on null

答案 1 :(得分:0)

问题是必须等待init。在这里我做了什么修复

_onCreate(Database db, int version) async {
  await db.execute('CREATE TABLE ... <YOUR QUERY CREATION GOES HERE>');
}

Future<Database> getDatabaseInstance() async {
  final String databasesPath = await getDatabasesPath();
  final String path = join(databasesPath, '<YOUR DB NAME>');

  return await openDatabase(path, version: 1, onCreate: _onCreate);
}

Future<int> save(Contact contact) {
  return getDatabaseInstance().then((db) {
    final Map<String, dynamic> contactMap = Map();
    contactMap['name'] = contact.name;
    contactMap['account_number'] = contact.accountNumber;
    return db.insert('contacts', contactMap);
  });
}

SQFlite页面提供了一个很好的示例,对您有很大帮助。 https://github.com/tekartik/sqflite/blob/master/sqflite/doc/opening_db.md