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

React Native/Ionic中导入300MB SQLite数据库做种子数据方案咨询

解决300MB大型SQLite种子数据在React Native/Ionic+Capacitor中的导入问题

针对你的语言词典应用场景,直接复制预生成的SQLite数据库文件是最高效的方案,完全避开JSON.stringify的内存溢出问题。如果确实需要用JSON格式导入,也可以通过分块方式实现,以下是具体方案:

方案一:直接复制预生成的SQLite数据库文件(推荐)

既然你已经有现成的300MB SQLite数据库,不需要转成JSON再导入,直接把数据库文件复制到应用的可读写目录即可:

实现步骤

  1. 将SQLite文件放入项目资源

    • 在Ionic项目的src/assets目录下创建databases文件夹,把你的词典数据库(比如dictionary.db)放入其中。
    • 在capacitor.config.ts中配置assets拷贝规则,确保文件能被打包到应用:
      export default defineConfig({
        // ...其他配置
        assets: {
          include: ['**/*', 'databases/**/*'],
        },
      });
      
  2. 使用Capacitor Filesystem API复制文件到可读写目录
    应用启动时先检查目标路径是否存在数据库,不存在则从assets复制:

    import { Filesystem, Directory, Encoding } from '@capacitor/filesystem';
    import { CapacitorSQLite, SQLiteConnection } from '@capacitor-community/sqlite';
    
    const sqliteConnection = new SQLiteConnection(CapacitorSQLite);
    
    async function initDatabase() {
      const dbName = 'dictionary.db';
      const targetDir = Directory.Data;
    
      // 检查数据库是否已存在
      try {
        await Filesystem.stat({ path: dbName, directory: targetDir });
        console.log('数据库已存在,直接连接');
        const db = await sqliteConnection.createConnection(dbName, false, 'no-encryption', 1);
        await db.open();
        // 后续查询操作
      } catch (error) {
        // 数据库不存在,从assets复制
        console.log('开始复制数据库文件');
        try {
          // 读取assets中的数据库文件
          const assetContent = await Filesystem.readFile({
            path: `databases/${dbName}`,
            directory: Directory.Assets,
            encoding: Encoding.Base64,
          });
          // 写入到应用私有可读写目录
          await Filesystem.writeFile({
            path: dbName,
            data: assetContent.data,
            directory: targetDir,
            encoding: Encoding.Base64,
          });
          console.log('数据库复制完成,开始连接');
          const db = await sqliteConnection.createConnection(dbName, false, 'no-encryption', 1);
          await db.open();
          // 后续查询操作
        } catch (copyError) {
          console.error('数据库复制失败:', copyError);
        }
      }
    }
    
    // 应用启动时调用初始化方法
    initDatabase();
    

注意事项

  • iOS平台:Capacitor的Filesystem默认有权限访问应用私有Data目录,无需额外配置。
  • Android平台:应用私有Data目录无需外部存储权限,Android 10+也无需适配requestLegacyExternalStorage。

方案二:分块导入JSON文件(若必须使用JSON)

如果种子数据只有JSON格式,可通过分块读取+批量插入的方式避免内存溢出:

实现思路

  1. 读取JSON文件内容(超大文件可预先拆分为多个小JSON文件)。
  2. 将数据按固定大小分块,每块调用SQLite的批量插入语句,同时开启事务提升插入效率。

代码示例

import { Filesystem, Directory } from '@capacitor/filesystem';
import { CapacitorSQLite, SQLiteConnection } from '@capacitor-community/sqlite';

const sqliteConnection = new SQLiteConnection(CapacitorSQLite);
const CHUNK_SIZE = 1000; // 每次插入1000条数据

async function importLargeJson() {
  const db = await sqliteConnection.createConnection('dictionary', false, 'no-encryption', 1);
  await db.open();

  // 读取JSON文件内容
  const jsonContent = await Filesystem.readFile({
    path: 'databases/dictionary.json',
    directory: Directory.Assets,
  });
  const dataArray = JSON.parse(jsonContent.data);

  // 开启事务提升插入速度
  await db.executeSql('BEGIN TRANSACTION');

  // 分块插入数据
  for (let i = 0; i < dataArray.length; i += CHUNK_SIZE) {
    const chunk = dataArray.slice(i, i + CHUNK_SIZE);
    // 构造批量插入占位符(根据你的表结构调整字段数量)
    const placeholders = chunk.map(() => '(?, ?, ?)').join(',');
    // 平铺字段值,匹配占位符顺序
    const values = chunk.flatMap(item => [item.id, item.word, item.definition]);

    await db.executeSql(`INSERT INTO words (id, word, definition) VALUES ${placeholders}`, values);
    console.log(`已插入 ${i + chunk.length} 条数据`);
  }

  await db.executeSql('COMMIT');
  await db.close();
}

内容的提问来源于stack exchange,提问作者appleman

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 00:00:00