database - 原因:SQL(查询)错误或缺少数据库。- 在颤振/飞镖中
问题描述
我试图构建一个应用程序,它接受标题、日期、链接、优先级,然后使用 Flutter 和 SQLite 显示它们。我最初在没有“链接”的情况下构建它并且它运行良好,但是当我添加归档的“链接”时,它给了我这个错误:
E/flutter ( 8491): [ERROR:flutter/lib/ui/ui_dart_state.cc(186)] Unhandled Exception: DatabaseException(table task_table has no column named link (code 1): , while compiling: INSERT INTO task_table (title, date, link, priority, status) VALUES (?, ?, ?, ?, ?)
E/flutter ( 8491): #################################################################
E/flutter ( 8491): Error Code : 1 (SQLITE_ERROR)
E/flutter ( 8491): Caused By : SQL(query) error or missing database.
E/flutter ( 8491): (table task_table has no column named link (code 1): , while compiling: INSERT INTO task_table (title, date, link, priority, status) VALUES (?, ?, ?, ?, ?))
E/flutter ( 8491): #################################################################) sql 'INSERT INTO task_table (title, date, link, priority, status) VALUES (?, ?, ?, ?, ?)' args [math, 2021-04-28T00:00:00.000, google, Medium, 0]}
与此相关的代码分布在两个文件中:一个数据库帮助文件,它基本上存储了数据库管理的所有功能
import 'dart:io';
import 'package:path_provider/path_provider.dart';
import 'package:sqflite/sqflite.dart';
import 'package:todo/models/task_model.dart';
class DatabaseHelper {
static final DatabaseHelper instance = DatabaseHelper._instance();
static Database _db;
DatabaseHelper._instance();
String taskTable = 'task_table';
String colId = 'id';
String colTitle = 'title';
String colDate = 'date';
String colLink = 'link';
String colPriority = 'priority';
String colStatus = 'status';
// task tables
// Id | Title | Date | Link | Priority | Status
// 0 '' '' '' ''
// 2 '' '' '' ''
// 3 '' '' '' ''
Future<Database> get db async {
if (_db == null) {
_db = await _initDb();
}
return _db;
}
Future<Database> _initDb() async {
Directory dir = await getApplicationDocumentsDirectory();
String path = dir.path + 'todo_list.db';
final todoListDb =
await openDatabase(path, version: 1, onCreate: _createDb);
return todoListDb;
}
void _createDb(Database db, int version) async {
await db.execute(
'CREATE TABLE $taskTable($colId INTEGER PRIMARY KEY AUTOINCREMENT, $colTitle TEXT, $colDate TEXT, $colLink TEXT, $colPriority TEXT, $colStatus INTEGER)');
}
Future<List<Map<String, dynamic>>> getTaskMapList() async {
Database db = await this.db;
final List<Map<String, dynamic>> result = await db.query(taskTable);
return result;
}
Future<List<Task>> getTaskList() async {
final List<Map<String, dynamic>> taskMapList = await getTaskMapList();
final List<Task> taskList = [];
taskMapList.forEach((taskMap) {
taskList.add(Task.fromMap(taskMap));
});
taskList.sort((taskA, taskB) => taskA.date.compareTo(taskB.date));
return taskList;
}
Future<int> insertTask(Task task) async {
Database db = await this.db;
final int result = await db.insert(taskTable, task.toMap());
return result;
}
Future<int> updateTask(Task task) async {
Database db = await this.db;
final int result = await db.update(taskTable, task.toMap(),
where: '$colId = ?', whereArgs: [task.id]);
return result;
}
Future<int> deleteTask(int id) async {
Database db = await this.db;
final int result =
await db.delete(taskTable, where: '$colId = ?', whereArgs: [id]);
return result;
}
}
第二个文件是数据库模型文件,其中包含数据库创建等:
class Task {
int id;
String title;
DateTime date;
String link;
String priority;
int status; // 0 - complete, 1- complete
Task({
this.title,
this.date,
this.link,
this.priority,
this.status,
});
Task.withId({
this.id,
this.title,
this.date,
this.link,
this.priority,
this.status,
});
Map<String, dynamic> toMap() {
final map = Map<String, dynamic>();
if (id != null) {
map['id'] = id;
}
map['title'] = title;
map['date'] = date.toIso8601String();
map['link'] = link;
map['priority'] = priority;
map['status'] = status;
return map;
}
factory Task.fromMap(Map<String, dynamic> map) {
return Task.withId(
id: map['id'],
title: map['title'],
date: DateTime.parse(map['date']),
link: map['link'],
priority: map['priority'],
status: map['status']);
}
}
这是我第一次在 Flutter 中使用数据库,因此非常感谢任何反馈。谢谢
解决方案
该错误表明您在表中没有可用的列。问题是每次启动应用程序时都不会创建数据库。您的问题有两种解决方案:
出于调试目的,只需删除应用程序并重新运行代码,这将使用正确的列重新生成数据库。警告:这仅用于调试,不适用于生产。
对于生产,当您在数据库上添加更改时,您必须增加数据库版本,在您的情况下从 1 到假设为 2。接下来,该
openDatabase
方法有一个参数onUpgrade
,将在升级数据库版本时调用,在您的情况下从1 到 2,在这里你必须运行额外的 sql 命令来更新你的表。像这样的东西:
await openDatabase(path, version: 1, onCreate: _createDb, onUpgrade: (db, old, newVersion) async {
if(old < 2) {
await db.execute("ALTER TABLE task_table ADD link TEXT");
}
});
另外不要忘记更新您的 create table 语句以在此处添加新列。
一种情况是您不想将 保存link
在数据库中,在这种情况下,您必须将其从 json serialization (your toMap
method) 中删除。
推荐阅读
- javascript - 试图包含一个简单的模块 - 无法让它工作纯 Javascript
- mysql - mysql查询找出三线经理
- mysql - InnoDB 字段类型大小与文件大小的差异?
- bash - WSL 启动显示“-bash: [: too many arguments”
- debugging - 反汇编程序在分析目标文件时如何维护寄存器的值?
- maven - Maven/Gradle 容器无法在内部 k8s 集群上构建项目
- mysql - Mysql - 您不能在 FROM 子句中指定要更新的目标表 - 子查询误解?
- php - 如何将表单数据插入 phpmyadmin 数据库?
- c# - 双击时如何禁用表单进入全屏模式
- vuejs2 - routeChange如何在framework7 Vuejs中使用?