Realm(JS)在Electron中打开数据库返回空对象问题求助
问题分析与解决方案
核心问题排查点及修复步骤
1. 数据库路径使用绝对路径
Electron主进程中相对路径的工作目录可能不符合预期,导致实际读写的数据库文件和你查看的不是同一个。建议用Electron的app.getPath('userData')生成绝对路径,确保数据库文件位置明确。
修改createConnection中的路径配置:
import { app } from 'electron'; import path from 'path'; // ... const dbPath = path.join(app.getPath('userData'), 'test.realm'); realm = await Realm.open({ schema: [TaskSchema, PersonSchema, DogSchema, CatSchema], path: dbPath, encryptionKey, });
2. 正确处理Realm查询结果的输出
realm.objects("Cat")返回的是Realm.Results对象,这是一个实时更新的集合,直接console.log会显示空对象(内部结构无法被普通控制台完全序列化)。需要转换为数组或访问具体属性验证数据:
修改getCat中的日志输出:
let cats = realm.objects("Cat"); console.log("cats count: ", cats.length); // 先查看数据数量 console.log("cats data: ", Array.from(cats)); // 转成数组查看具体内容
3. 确保操作顺序的正确性
必须保证createConnection执行完成(Realm实例初始化完成)后,再调用createCat和getCat。渲染进程中要等待createConnection的Promise完成后再执行后续操作,避免使用未初始化的realm变量。
4. 加密密钥的合理性(可选)
当前使用全0的Int8Array作为加密密钥,虽然Realm允许,但测试阶段可以暂时移除encryptionKey配置,排除加密相关的潜在问题:
realm = await Realm.open({ schema: [TaskSchema, PersonSchema, DogSchema, CatSchema], path: dbPath, // encryptionKey, // 暂时注释,测试加密是否影响 });
5. 主进程Realm实例的跨上下文问题
直接将Realm实例返回给渲染进程会因Electron上下文隔离导致序列化丢失,因此不要在IPC返回中传递Realm实例。主进程应封装所有数据库操作,渲染进程仅调用IPC方法获取处理后的数据,而非直接操作Realm对象。
比如修改getCat直接返回数据数组:
ipcMain.handle('getCat', async (event, message) => { const cats = realm.objects("Cat"); const catList = Array.from(cats); console.log("cats data: ", catList); return { status: "ok", data: catList } })
完整修改后的示例代码
import Realm from "realm"; import { app, ipcMain } from 'electron'; import path from 'path'; const TaskSchema = { name: "Task", properties: { _id: "int", name: "string", priority: "int?", progressMinutes: "int?", }, primaryKey: "_id", }; const PersonSchema = { name: "Person", properties: { name: "string", age: "int?", }, }; const DogSchema = { name: "Dog", properties: { name: "string", owner: "Person?", age: "int?", }, }; const CatSchema = { name: "Cat", properties: { name: "string", }, }; let realm: Realm; ipcMain.handle('createConnection', async (event, message) => { console.log('message', message); const dbPath = path.join(app.getPath('userData'), 'test.realm'); // const encryptionKey = new Int8Array(64); try { realm = await Realm.open({ schema: [TaskSchema, PersonSchema, DogSchema, CatSchema], path: dbPath, // encryptionKey, }); console.log("Realm连接成功,实例状态:", realm.isClosed ? "已关闭" : "已打开"); } catch (err) { console.log("连接错误:", err); return { status: "error", message: err }; } return { status: "ok" }; // 不返回Realm实例 }) ipcMain.handle('createCat', async (event, message) => { if (!realm || realm.isClosed) { console.log("Realm实例未初始化或已关闭"); return { status: "error", message: "数据库未连接" }; } try { let cat: Realm.Object; realm.write(() => { cat = realm.create("Cat", { name: "Max" }); }); console.log("创建Cat成功:", cat); } catch (err) { console.log("创建Cat错误:", err); return { status: "error", message: err }; } return { status: "ok" } }) ipcMain.handle('getCat', async (event, message) => { if (!realm || realm.isClosed) { console.log("Realm实例未初始化或已关闭"); return { status: "error", message: "数据库未连接" }; } const cats = realm.objects("Cat"); const catList = Array.from(cats); console.log("Cat数量:", cats.length, "数据:", catList); return { status: "ok", data: catList } })
内容的提问来源于stack exchange,提问作者Riccoh
相关产品推荐
相关产品推荐

