React Native/Ionic中导入300MB SQLite数据库做种子数据方案咨询
解决300MB大型SQLite种子数据在React Native/Ionic+Capacitor中的导入问题
针对你的语言词典应用场景,直接复制预生成的SQLite数据库文件是最高效的方案,完全避开JSON.stringify的内存溢出问题。如果确实需要用JSON格式导入,也可以通过分块方式实现,以下是具体方案:
方案一:直接复制预生成的SQLite数据库文件(推荐)
既然你已经有现成的300MB SQLite数据库,不需要转成JSON再导入,直接把数据库文件复制到应用的可读写目录即可:
实现步骤
将SQLite文件放入项目资源
- 在Ionic项目的
src/assets目录下创建databases文件夹,把你的词典数据库(比如dictionary.db)放入其中。 - 在
capacitor.config.ts中配置assets拷贝规则,确保文件能被打包到应用:export default defineConfig({ // ...其他配置 assets: { include: ['**/*', 'databases/**/*'], }, });
- 在Ionic项目的
使用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格式,可通过分块读取+批量插入的方式避免内存溢出:
实现思路
- 读取JSON文件内容(超大文件可预先拆分为多个小JSON文件)。
- 将数据按固定大小分块,每块调用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
相关产品推荐
相关产品推荐

