从 CSV 文件填充 Android 数据库?

Posted

技术标签:

【中文标题】从 CSV 文件填充 Android 数据库?【英文标题】:Populate Android Database From CSV file? 【发布时间】:2011-02-22 15:31:55 【问题描述】:

是否可以获取存储在 res/raw 资源目录中的 csv 文件并使用它来填充 sqlite3 数据库中的表?

我的想法是,如果有一种方法可以将整个文件批量导入到表中,那么这将比遍历文件中的每一行并执行单独的插入语句更干净、更快捷......

我发现有一个 sqlite 导入命令允许这样做:How to import load a .sql or .csv file into SQLite?

...但我无法在我的 android 应用程序中应用这些语句。我的第一个想法是尝试以下方法......但没有运气:

db.execSQL("CREATE TABLE " + TABLE_NAME + "(id INTEGER PRIMARY KEY, name TEXT)");
db.execSQL(".mode csv");
db.execSQL(".import res/raw/MyFile.csv " + TABLE_NAME); 

这可能吗?

我应该尝试不同的方法来填充我的数据库吗?

更新:我将 Josef 的回复标记为答案(使用事务进行批量插入),因为它可以正常工作并根据我的标题直接回答我的问题(感谢 Josef)。但是,我仍在寻找一种方法,使用 import 语句在 Android 应用程序中从 csv 文件批量插入到 sqlite3 表中。如果您知道该怎么做,请回复。

感谢您的回答!

【问题讨论】:

【参考方案1】:

如果您想将静态数据与您的应用程序打包在一起,我建议您在开发时准备数据库(使用您喜欢的任何 UI 或 csv-import 命令)并将 sqlite 文件传送到 assets 文件夹中。然后,您可以在应用程序首次运行时简单地将整个 sqlite 文件复制到设备上。 These posts 带你了解这个想法,这很可能是设置数据库的最快方法(文件复制速度)。

如果由于某种原因您确实需要在运行时插入大量数据,我建议您查看bulk insert using transactions 的方法以加快速度。

【讨论】:

感谢 Josef 的回复,我已尝试将 sqlite3 .db 文件发送到 .apk 的 assets 文件夹中(如规则设计帖子大纲)。我在使用规则设计解决方案时遇到的问题是,当我的数据库版本 # 更改时,不会调用 onUpgrade()。事实上,我可以让它用较新版本替换现有数据库的唯一方法是解决 onUpgrade() 并添加一条语句,在调用 createDataBase() 之前显式删除数据库(这基本上迫使你每次运行 Activity 时重新创建数据库... =( 至于使用可能是可行解决方案的事务。当我实现这个解决方案(screaming-penguin.com/node/7742)时,我能够让 onUpgrad() 保持调用一致性,但考虑到使规则设计解决方案工作所需的升级和调整(即'_id),一个简单的 sql 导入语句仍然是理想的' 列和 'android_metadata' 表)。虽然这些调整并不难实现,但我担心它会为 Android 平台期望创建其数据库的方式增加不必要的依赖。如果这种情况发生改变,我们的解决方案也会改变...... 使用预构建的 sqlite3 文件发送不是一个好习惯。制造商可以在后台实现/使用他们想要的任何技术,但必须遵守 sqlite3 接口 - 因此您预构建的 sqlite3 可能无法在某些设备上运行。因此,最佳/最安全的做法是始终让您的设备创建数据库,然后批量导入。 有an even faster way to do bulk insert 不只是使用事务。【参考方案2】:

我花了很多时间寻找一个简单的解决方案,并自己想出了这段代码。对于像我一样寻找这个的未来人,你可以使用这个:

BufferedReader in = new BufferedReader(your csv file source here);
String reader = "";
while ((reader = in.readLine()) != null)
    String[] RowData = reader.split(",");
    date = RowData[0];
    value = RowData[1];
    ContentValues values = new ContentValues();
    values.put(CsvProvider.DATE, date);
    values.put(CsvProvider.VALUE, value);
    getContentResolver().insert(CsvProvider.CONTENT_URI, values);

in.close();

我的CSV 文件没有标题,只有 2 列,但多于两列应该不是问题。请记住指定拆分列的内容,并为每一列添加另一个 RowData[#](您必须从 0 开始)。在致电in.close() 之前,您要确保对每一行所做的任何事情都已完成。我正在使用内容提供程序,但您真的可以对数据做任何您想做的事情,例如将其附加到 String[] 或其他任何内容。

当我使用输入流时,您可以将 BufferedReader 指向您想要的任何位置。只要BufferedReader 可以读取它就可以工作。

【讨论】:

那个分隔符很痛苦。我不知道为什么人们开始使用它。我正在尝试将其从文件中删除,但它仍然存在。有什么方法可以使用逗号或其他字符,还是来自某个网​​络服务器? 不..它必须是“|”,因为有 700-800k 记录并且我使用“,”作为数据..:(..无论如何我让它工作了......我用过用于拆分的 StringTokenizer .. 仍然无法解决问题.. 我确实将文件拆分为每个 1mb .. 我使用 AsyncTask 并能够插入 5k 条记录.. 之后缓冲区中断了... 奇怪的是它花了很长时间只是为了复制和创建数据库...我什至还没有开始开发应用程序...:( 是的,我有 2049 条记录要导入,导入最多需要 60 秒。那太长了。我已经尝试过交易,但我得到了 nullpointerexceptions。但我确实将数据放入我的数据库中。 5k 条记录需要多长时间? 如何去掉数据周围的“”??

以上是关于从 CSV 文件填充 Android 数据库?的主要内容,如果未能解决你的问题,请参考以下文章

通过 python 将 csv 文件插入 MySQL。运行但数据未填充到表中

如何从android下载firebase数据库作为CSV文件

上传 .csv 或 .txt 文件以填充 QTableView

从脚本自动填充 Access 数据库

在 python 中从模板文件和 csv 数据生成输出文件

我的Android进阶之旅Android Studio中如何快速查找空行