uni-app在sqlite相关开发过程中 热更新代码后无法update与insert 提示readonly database
uni-app在sqlite相关开发过程中 热更新代码后无法update与insert 提示readonly database
操作步骤:
- 打开App
- 打开数据库
- 用select语句随便查询一条数据,可以查询成功
- 用insert语句随便插入一条数据,可以插入成功
- 随便改一点uniapp的代码,等待代码热更新到手机并等待App重启
- 重启成功后打开数据库
- 用select语句随便查询一条数据,可以查询成功
- 用insert语句随便插入一条数据,插入报错,错误内容Attempt to write a readonly database
预期结果:
在代码热刷新后可以正常的insert或者update
实际结果:
在代码热刷新后在insert或者update时提示Attempt to write a readonly database,但db文件是创建在_doc目录下的。
bug描述:
在开发过程中经过热刷新代码后,update与insert的操作就会一直提示Attempt to write a readonly database. Cannot create file private directory,在后台彻底关闭App并再重新打开后就可以update与insert的操作。但不管有没有经过热刷新,打开数据与查询等操作都是可以的。
数据库是创建在_doc目录下
plus.sqlite.openDatabase({
name: _this.dbName, //数据库名称
path: _doc/${_this.dbName}.db
, //数据库地址
success(e) { 数据库开启后的相关操作 },
fail(e) {}
})
insert操作:
plus.sqlite.executeSql({
name: _this.dbName,
sql: sqlStr,
success(e) {},
fail(e) {}
})
开发环境 | 版本号 | 项目创建方式 |
---|---|---|
PC开发环境操作系统 | Mac | HBuilderX |
PC开发环境操作系统版本号 | 11.6 | |
HBuilderX类型 | 正式 | |
HBuilderX版本号 | 3.2.16 | |
手机系统 | iOS | |
手机系统版本号 | iOS 13.2 | |
手机厂商 | 苹果 | |
手机机型 | iPhone 6S | |
页面类型 | vue | |
vue版本 | vue2 | |
打包方式 | 云端 |
求官方看看这个问题
临时解决方案: 每次open db后测试一下insert一条数据,如果报错则先close db,然后open db就没有问题了。这是bug还是我的姿势不对?
插入前用isOpenDatabase 判断下数据库是否打开
热更新之前的数据库会关闭,重新open就可以了
每次App打开的时候都会主动去打开数据库的,如果没有开启就会开启再进行接下来的操作。关键是打开后可以查询,但是update和insert就会有问题。从目前的测试来看,热更新之前数据库并没有被关闭,在热更新之后去检查状态是开启的,这种情况下可以查询,但不能update和insert。
回复 g***@tocs.cn: 你是怎么检测状态是开启的。在你的代码里没有看到
回复 g***@tocs.cn: 现在有好的处理方法没?我也遇到了相同的问题,之前版本的HBuildx是没有问题的 更新了版本后就有这个问题了,小改点东西 程序必须重启才能不报错。
回复 1***@qq.com: 热更新后要重新open
碰到同样问题
碰到同样问题
3.5.3已修复
使用发现 错误:{“code”:-1404,“message”:"android.database.sqlite.SQLiteReadOnlyDatabaseException: attempt to write a readonly database (Sqlite code 8 SQLITE_READONLY), (OS error - 2:No such file or directory)
下面是写法:
plus.sqlite.executeSql({
name: ‘main’,
sql: INSERT INTO bs_xuewei VALUES (2989, 0, ‘0’, ‘其他’, ‘’, 0, 1, ‘无学位’, 1, 1, 0, 0);,
success(res) {
console.log(‘成功:’+ res)
},
fail(err) {
console.log(‘错误:’+ JSON.stringify(err))
}
})
使用的是安卓,机型为:huawei matepad air ,harmonyOs4.0.0版本
解决了吗?
是怎么解决的,现在还是有这个问题
这个问题解决了吗?我现在也遇到了这个问题,select可以,但是insert不行,提示数据据只读
module.exports = {
dbName: ‘tools’, // 数据库名称
dbPath: ‘static/db/tools.db’, // 数据库地址,推荐以下划线为开头 _doc/xxx.db
//创建数据库 或 有该数据库就打开
openSqlite() {
return new Promise((resolve, reject) => {
// 打开数据库
plus.sqlite.openDatabase({
name: this.dbName,
path: this.dbPath,
success(e) {
resolve(e);
},
fail(e) {
reject(e);
}
})
})
},
}
在uni-app中使用SQLite进行开发时,遇到热更新后数据库变为只读(readonly database)的问题,通常是由于数据库文件在热更新过程中被锁定或路径问题导致的。这里提供一些可能的解决方案和代码示例,帮助你排查和修复这个问题。
1. 确保数据库文件路径正确
热更新可能会改变应用的运行目录,从而影响数据库文件的路径。确保数据库文件的路径是相对于应用根目录的绝对路径,或者在每次启动时重新计算路径。
// 获取应用根目录
const rootDir = uni.getSystemInfoSync().userDataPath;
const dbPath = `${rootDir}/mydatabase.db`;
// 打开数据库
const db = uni.openDatabase({
name: 'mydatabase',
path: dbPath,
success: function () {
console.log('Database opened successfully');
},
fail: function (err) {
console.error('Failed to open database:', err);
}
});
2. 检查数据库文件是否被其他进程占用
在某些情况下,其他进程(如之前的应用实例)可能仍在占用数据库文件。确保在应用启动时关闭所有可能打开数据库的连接,或者在设备重启后尝试。
3. 使用try-catch捕获异常并处理
在执行数据库操作时,使用try-catch结构捕获异常,以便更好地了解问题所在。
try {
db.execSQL({
sql: 'INSERT INTO mytable (column1, column2) VALUES (?, ?)',
values: ['value1', 'value2'],
success: function () {
console.log('Insert successful');
},
fail: function (err) {
console.error('Insert failed:', err);
if (err.message.includes('readonly')) {
console.error('Database is readonly. Possible reasons: file locked, path issue.');
}
}
});
} catch (error) {
console.error('Error executing SQL:', error);
}
4. 清理缓存和重启应用
在热更新后,尝试清理应用的缓存数据,并重启应用,以确保所有资源都被正确加载。
5. 检查设备和操作系统限制
某些设备和操作系统版本可能对数据库文件的访问权限有限制。确保应用有足够的权限访问存储位置。
总结
以上代码和策略可以帮助你排查和解决uni-app中SQLite数据库在热更新后变为只读的问题。如果问题依旧存在,建议详细检查应用的日志输出,或者考虑在应用商店发布新版本前,在更多设备和环境中进行充分测试。