我老是听到这个恼人的消息!
当数据插入本地数据库时,我看到了这条消息。
JNI critical lock held for 30.083ms on Thread[27,tid=23883,Runnable,Thread*=0xce150a00,peer=0x12cc0190,"Sqflite"]
如果我从表中选择数据,我将得到
W/CursorWindow(23809): Window is full: requested allocation 3095146 bytes, free space 2096696 bytes, window size 2097152 bytes
E/SQLiteQuery(23809): exception: Row too big to fit into CursorWindow requiredPos=0, totalRows=1; query: SELECT * FROM description_table;
I/flutter (23809): DatabaseException(Row too big to fit into CursorWindow requiredPos=0, totalRows=1) sql 'SELECT * FROM defect_description_table;' args []}
我没有任何blob数据,都是字符串。那为什么会发生这种事?
在这里,json结构
[{ "id": 1, "name": "Descriptions","data": [{..},{...} ... ]},{....},{....}]
我认为问题在数据列表上,因为它包含了大量的数据(它有10298)?
解决这个问题的办法是什么?
我的插入方法
Future insertData(
BuildContext context, String urls, String accessToken) async {
CategoryTableData categoryData = CategoryTableData();
try {
var desc = List<Desc>();
var headers = {
'authorization': "Bearer" + " " + accessToken,
"Accept": "application/json"
};
var url = xxx;
var response = await http.get(url, headers: headers);
var res = json.decode(response.body);
for (var i in res) {
if (i['name'] == "Descriptions") {
desc.add(Desc(
id: i['id'], name: i['name'], data: i['data']));
}
}
await dao.batch((b) {
b.insertAll(_dao.descTable, desc);
});
categoryData = await _dao.selectAllCategories();
return categoryData;
} catch (e) {
print(e);
categoryData = await _dao.selectAllCategories();
return categoryData;
}
}
Desc
class Desc extends Table {
IntColumn get id => integer().nullable()();
TextColumn get name => text().named("name").nullable()();
TextColumn get data => text().map(const ListConverter()).nullable()();
}
发布于 2021-03-11 05:01:48
消息Window is full: requested allocation 3095146 bytes, free space 2096696 bytes, window size 2097152 bytes
告诉您,您正在尝试将一行(* =所有列)放入游标窗口(缓冲区)中,即3095146字节,该游标窗口(缓冲区)有2096696字节,没有2097152 (2Mb)可用字节。
简单地说,要提取的数据太多了。当您插入数据时,这不是问题,因为没有中间缓冲区和相对有限的缓冲区(游标窗口)。
当尝试检索商店映像时,您经常会看到这种情况。
有各种方法可以用来规避这个问题。
- You could select potions of data utilising the [length(column\_name) function](https://sqlite.org/lang_corefunc.html#length), perhaps using the [CASE WHEN THEN ELSE END](https://sqlite.org/lang_expr.html#the_case_expression) expression/construct and then build the full data when it has been retrieved.
- It may be that you are inadvertently storing more data, e.g. accidentally concatenating data in a loop.
您需要了解所存储的数据,才能知道上述哪一项可能有用。
https://stackoverflow.com/questions/66576412
复制相似问题