在 Android 本机中访问使用 Flutter 创建的数据库时获取 SQLiteException
Getting SQLiteException while accessing the database created with Flutter in Android native
我在 Android 本机中遇到错误 no such table
。数据库是用 Flutter sqflite
包创建的。数据库存在于目录中。数据库和 table 名称被检查并确认了不止一次。我不知道本机代码有什么问题。它与 Dart/Flutter.
一起工作得很好
我们是否无法访问 Dart/Flutter 在 Android 原生中创建的数据库,或者方法有些不同?
Android 侧的代码。
public static Cursor getDB(Context context){
myDB = SQLiteDatabase.openDatabase(context.getDatabasePath(DB_NAME).getAbsolutePath(), null, SQLiteDatabase.OPEN_READWRITE);
String query = "SELECT * FROM todo";
return myDB.rawQuery(query, null);
}
数据库创建Dart代码
final String _DB_NAME = "todos.db";
final String tableTodo = 'todo';
final String columnId = '_id';
final String columnTitle = 'title';
Future<Database> initializeDB() async {
String dbDir = await getDatabasesPath();
String dbPath = dbDir + _DB_NAME;
var database = await openDatabase(dbPath, version: 1, onCreate: _createDB);
return database;
}
void _createDB(Database db, int version) async {
await db.execute(
'create table $tableTodo ($columnId INTEGER PRIMARY KEY AUTOINCREMENT, $columnTitle TEXT NOT NULL)');
}
提前致谢!
您可能没有打开同一个数据库。看来你没有在 flutter 方面正确构建 dbPath
。如果你简单地打印它,你应该看到你在路径
中缺少一个 /
而不是
String dbPath = dbDir + _DB_NAME;
尝试(从 path
套餐加入):
var dbPath = join(dbDir, _DB_NAME);
或者干脆
var dbPath = _DB_NAME;
I am getting an error no such table in Android native.
如果数据库不存在,Android SQLite API 的 openDatabase
方法将在给定路径创建一个空数据库。
table not found 是 no file existing at the specified path (根本原因很可能在后面介绍的Flutter代码中).
理想情况下,您应该在打开数据库之前检查文件是否存在。
所以沿着 :-
public static Cursor getDB(Context context){
if (context.getDatabasePath(DB_NAME).exists()) {
myDB = SQLiteDatabase.openDatabase(context.getDatabasePath(DB_NAME).getAbsolutePath(), null, SQLiteDatabase.OPEN_READWRITE);
String query = "SELECT * FROM todo";
return myDB.rawQuery(query, null);
} else {
// handle the file not existing
}
}
The database exists in the dir.
如前所述,数据库将在事后存在。上面的代码检查文件(它不会进一步检查返回的文件是否是普通文件(File 的 isFile()
方法)或可以进行的其他检查)
- 其他检查可能是:-
检查文件的长度应至少为 4k,如果它有用户定义的 table 并且您已使用 AUTOINCREMENT
(这会创建另一个内部 table sqlite_sequence) 至少 12k(每个 table 至少 4k,包括始终存在的 sqlite_master table) .
打开文件并检查文件头的前 16 个字节应符合 SQLite Database File Format
- 每个有效的 SQLite 数据库文件都以以下 16 个字节(十六进制)开头:53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00。此字节序列对应于 UTF -8 字符串 "SQLite format 3" 包括末尾的 nul 终止符。
使用 openDatabase 方法打开数据库后,您可以检查 sqlite_master 以查看 table(s) 是否按预期存在。
Is it like we can't access the database created with Dart/Flutter in Android native or the approach is somehow different?
从对 SQlite plugin for Flutter 的快速扫描中可以看出:-
A SQLite database is a file in the file system identified by a path. If relative, this path is relative to the path obtained by getDatabasesPath(), which is the default database directory on Android and the documents directory on iOS.
这表明Flutter使用了getDatabasePath()
方法,因此看起来它们是兼容的,并且可能Flutter使用底层原生android sqlite api.
查看 documentation 似乎您没有按照建议打开数据库。给出的示例使用:-
// Get a location using getDatabasesPath
var databasesPath = await getDatabasesPath();
String path = join(databasesPath, 'demo.db');
猜测添加文件分隔符然后 demo.db 所以而不是 data/data//databasetodos.db (看起来是由您的代码生成的) 上面的示例将使用 (如果 demo.db 更改为 todos.db) /data/data//databases/todos.db
- 您可能希望检查是否存在这样的文件,并可能相应地移动和重命名它(这样可以避免重新生成任何数据,但您可能无法访问该文件)
因此我认为您的 Flutter 代码应该是:-
final String _DB_NAME = "todos.db";
final String tableTodo = 'todo';
final String columnId = '_id';
final String columnTitle = 'title';
Future<Database> initializeDB() async {
String dbDir = await getDatabasesPath();
String dbPath = join(dbDir,_DB_NAME);
var database = await openDatabase(dbPath, version: 1, onCreate: _createDB);
return database;
}
void _createDB(Database db, int version) async {
await db.execute(
'create table $tableTodo ($columnId INTEGER PRIMARY KEY AUTOINCREMENT, $columnTitle TEXT NOT NULL)');
}
我在 Android 本机中遇到错误 no such table
。数据库是用 Flutter sqflite
包创建的。数据库存在于目录中。数据库和 table 名称被检查并确认了不止一次。我不知道本机代码有什么问题。它与 Dart/Flutter.
我们是否无法访问 Dart/Flutter 在 Android 原生中创建的数据库,或者方法有些不同?
Android 侧的代码。
public static Cursor getDB(Context context){
myDB = SQLiteDatabase.openDatabase(context.getDatabasePath(DB_NAME).getAbsolutePath(), null, SQLiteDatabase.OPEN_READWRITE);
String query = "SELECT * FROM todo";
return myDB.rawQuery(query, null);
}
数据库创建Dart代码
final String _DB_NAME = "todos.db";
final String tableTodo = 'todo';
final String columnId = '_id';
final String columnTitle = 'title';
Future<Database> initializeDB() async {
String dbDir = await getDatabasesPath();
String dbPath = dbDir + _DB_NAME;
var database = await openDatabase(dbPath, version: 1, onCreate: _createDB);
return database;
}
void _createDB(Database db, int version) async {
await db.execute(
'create table $tableTodo ($columnId INTEGER PRIMARY KEY AUTOINCREMENT, $columnTitle TEXT NOT NULL)');
}
提前致谢!
您可能没有打开同一个数据库。看来你没有在 flutter 方面正确构建 dbPath
。如果你简单地打印它,你应该看到你在路径
/
而不是
String dbPath = dbDir + _DB_NAME;
尝试(从 path
套餐加入):
var dbPath = join(dbDir, _DB_NAME);
或者干脆
var dbPath = _DB_NAME;
I am getting an error no such table in Android native.
如果数据库不存在,Android SQLite API 的 openDatabase
方法将在给定路径创建一个空数据库。
table not found 是 no file existing at the specified path (根本原因很可能在后面介绍的Flutter代码中).
理想情况下,您应该在打开数据库之前检查文件是否存在。
所以沿着 :-
public static Cursor getDB(Context context){
if (context.getDatabasePath(DB_NAME).exists()) {
myDB = SQLiteDatabase.openDatabase(context.getDatabasePath(DB_NAME).getAbsolutePath(), null, SQLiteDatabase.OPEN_READWRITE);
String query = "SELECT * FROM todo";
return myDB.rawQuery(query, null);
} else {
// handle the file not existing
}
}
The database exists in the dir.
如前所述,数据库将在事后存在。上面的代码检查文件(它不会进一步检查返回的文件是否是普通文件(File 的 isFile()
方法)或可以进行的其他检查)
- 其他检查可能是:-
检查文件的长度应至少为 4k,如果它有用户定义的 table 并且您已使用
AUTOINCREMENT
(这会创建另一个内部 table sqlite_sequence) 至少 12k(每个 table 至少 4k,包括始终存在的 sqlite_master table) .打开文件并检查文件头的前 16 个字节应符合 SQLite Database File Format
- 每个有效的 SQLite 数据库文件都以以下 16 个字节(十六进制)开头:53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00。此字节序列对应于 UTF -8 字符串 "SQLite format 3" 包括末尾的 nul 终止符。
使用 openDatabase 方法打开数据库后,您可以检查 sqlite_master 以查看 table(s) 是否按预期存在。
Is it like we can't access the database created with Dart/Flutter in Android native or the approach is somehow different?
从对 SQlite plugin for Flutter 的快速扫描中可以看出:-
A SQLite database is a file in the file system identified by a path. If relative, this path is relative to the path obtained by getDatabasesPath(), which is the default database directory on Android and the documents directory on iOS.
这表明Flutter使用了getDatabasePath()
方法,因此看起来它们是兼容的,并且可能Flutter使用底层原生android sqlite api.
查看 documentation 似乎您没有按照建议打开数据库。给出的示例使用:-
// Get a location using getDatabasesPath
var databasesPath = await getDatabasesPath();
String path = join(databasesPath, 'demo.db');
猜测添加文件分隔符然后 demo.db 所以而不是 data/data//databasetodos.db (看起来是由您的代码生成的) 上面的示例将使用 (如果 demo.db 更改为 todos.db) /data/data//databases/todos.db
- 您可能希望检查是否存在这样的文件,并可能相应地移动和重命名它(这样可以避免重新生成任何数据,但您可能无法访问该文件)
因此我认为您的 Flutter 代码应该是:-
final String _DB_NAME = "todos.db";
final String tableTodo = 'todo';
final String columnId = '_id';
final String columnTitle = 'title';
Future<Database> initializeDB() async {
String dbDir = await getDatabasesPath();
String dbPath = join(dbDir,_DB_NAME);
var database = await openDatabase(dbPath, version: 1, onCreate: _createDB);
return database;
}
void _createDB(Database db, int version) async {
await db.execute(
'create table $tableTodo ($columnId INTEGER PRIMARY KEY AUTOINCREMENT, $columnTitle TEXT NOT NULL)');
}