You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 19:10:04