gpt4 book ai didi

android - 如何将房间数据库导出为 .CSV

转载 作者:行者123 更新时间:2023-12-02 01:31:39 25 4
gpt4 key购买 nike

如何将我的房间数据库导出到 .CSV 文件。我希望将其保存到设备存储中。我搜索了所有内容,但没有合适的答案。我希望有办法解决这个问题。

最佳答案

您不能只将数据库保存为 CSV。但是,如果完全检查点,数据库只是一个文件。如果没有完全检查点,那么它将是三个文件(除非预写日志记录被禁用)。

数据库本身由多个部分组成,一个标题(文件的前 100 个字节),然后是各个组件的数据 block 。其中大部分依赖于模式(表),也有系统表

  • sqlite_master 是一个包含模式的表
  • 如果 autogenerate = true 用于整数类型的主键,那么还有 sqlite_sequence 表
  • room 本身有 room_master_table,其中 room 存储一个散列,这是与基于 Room 预期模式的编​​译散列进行比较。

将所有数据保存为 CSV 文件会很复杂(而且没有必要,因为您只需复制数据库文件即可)。

如果您想要的是应用程序数据的 CSV,那么这将取决于表格。如果您是单个表,那么将数据提取为 CSV 会相对简单,但如果数据包含逗号,则可能会很复杂。

如果有多个表,那么你就必须区分表的数据。

同样是最简单的方法,如果只是保护数据就是复制文件。

然而,作为一个基于 :-

的例子

一个有 3 个表的数据库(除了系统表)

  • PostDataLocal(列见下文)
  • 本地组数据
  • AdminDataLocal
    • 已经为示例改编了现有答案

然后:-

@Dao 注释接口(interface)(即 AllDao)中的以下内容:-

@Query("SELECT postId||','||content FROM postDataLocal")
fun getPostDataLocalCSV(): List<String>
@Query("SELECT groupPostIdMap||','||groupId||','||groupName FROM groupDataLocal")
fun getGroupDataLocalCSV(): List<String>
@Query("SELECT adminGroupIdMap||','||userId||','||adminName||','||avatar FROM adminDataLocal")
fun getAdminDataLocalCSV(): List<String>

下面的函数是dao是先前实例化的 AllDao 实例:-

private fun createCSV() {

val sb = StringBuilder()
var afterFirst = false
sb.append("{POSTDATALOCAL}")
for (s in dao.getPostDataLocalCSV()) {
if(afterFirst) sb.append(",")
afterFirst = true
sb.append(s)
}
afterFirst = false
sb.append("{GROUPDATALOCAL}")
for (s in dao.getGroupDataLocalCSV()) {
if (afterFirst) sb.append(",")
afterFirst = true
sb.append(s)
}
afterFirst = false
sb.append("{ADMINDATALOCAL}")
for (s in dao.getAdminDataLocalCSV()) {
if ((afterFirst)) sb.append(",")
afterFirst = true
sb.append(s)
}
Log.d("CSV_DATA","CSV is :-\n\t$sb")

}

然后在一个 Activity (其中已实例化 dao)中执行以下操作:-

createCSV() 

然后,当数据库包含以下数据(通过 App Inspection 提取)时:-

PostDataLocal

  • enter image description here

本地组数据

  • enter image description here

AdminDataLocal

  • enter image description here

写入日志的结果(可以写入文件而不是日志)是:-

D/CSV_DATA: CSV is :-
{POSTDATALOCAL}1,Post001,2,Post002,3,Post003{GROUPDATALOCAL}1,1,Group001 (Post001),1,2,Group002 (Post001),1,3,Group003 (Post001),2,4,Group004 (Post002),2,5,Group005 (Post002),3,6,Group006 (Post003){ADMINDATALOCAL}1,1,Admin001,admin001.gif,1,2,Admin002,admin002.gif,1,3,Admin003,admin003.gif,2,4,Admin004,admin004.gif,2,5,Admin005,admin005.gif,3,6,Admin006,admin006.gif,4,7,Admin007,admin007.gif,5,8,Admin008,admin008.gif,6,9,Admin009,admin009.gif,6,10,Admin010,admin010.gif
  • 注意如何包含标题以区分表格
  • 当然没有考虑在数据中包含逗号(以上只是为了说明原则上您可以相对轻松地生成数据的 CSV 表示形式)

额外的

这是一个更自动化的版本,您不需要在其中创建带 @Query 注释的函数,而是询问 sqlite_master 以提取表并使用 table_info pragma 来确定列,从而构建相应的 SQL。

因此它应该适用于任何 Room 数据库。

它还允许用逗号指示符替换数据中的逗号,然后在处理 CSV 时可以替换逗号。

支持(次要/由主要调用)功能是:-

private fun getTableColumnNames(tableName: String, suppDB: SupportSQLiteDatabase): List<String> {
val rv = arrayListOf<String>()
val csr = suppDB.query("SELECT name FROM pragma_table_info('${tableName}')",null)
while (csr.moveToNext()) {
rv.add(csr.getString(0))
}
csr.close()
return rv.toList()
}

主要功能:-

private fun AutoCreateCSV(): String {
val replaceCommaInData = "{COMMA}" /* commas in the data will be replaced by this */
val rv = StringBuilder()
val sql = StringBuilder()
var afterFirstTable = false
var afterFirstColumn = false
var afterFirstRow = false
val suppDb = db.getOpenHelper().writableDatabase
var currentTableName: String = ""
val csr = db.query("SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE('sqlite_%') AND name NOT LIKE('room_%') AND name NOT LIKE('android_%')", null)
while (csr.moveToNext()) {
sql.clear()
sql.append("SELECT ")
currentTableName = csr.getString(0)
if (afterFirstTable) rv.append(",")
afterFirstTable = true
afterFirstColumn = false
rv.append("{$currentTableName},")
for (columnName in getTableColumnNames(currentTableName,suppDb)) {
if (afterFirstColumn) sql.append("||','||")
afterFirstColumn = true
sql.append("replace(`$columnName`,',','$replaceCommaInData')")
}
sql.append(" FROM `${currentTableName}`")
val csr2 = db.query(sql.toString(),null)
afterFirstRow = false
while (csr2.moveToNext()) {
if (afterFirstRow) rv.append(",")
afterFirstRow = true
rv.append(csr2.getString(0))
}
csr2.close()
}
csr.close()
return rv.toString()
}

使用相同的数据并作为主函数返回字符串以下代码Log.d("CSV_DATA2",AutoCreateCSV())结果:-

D/CSV_DATA2: {PostDataLocal},1,Post001,2,Post002,3,Post003,{GroupDataLocal},1,1,Group001 (Post001),1,2,Group002 (Post001),1,3,Group003 (Post001),2,4,Group004 (Post002),2,5,Group005 (Post002),3,6,Group006 (Post003),{AdminDataLocal},1,1,Admin001,admin001.gif,1,2,Admin002,admin002.gif,1,3,Admin003,admin003.gif,2,4,Admin004,admin004.gif,2,5,Admin005,admin005.gif,3,6,Admin006,admin006.gif,4,7,Admin007,admin007.gif,5,8,Admin008,admin008.gif,6,9,Admin009,admin009.gif,6,10,Admin010,admin010.gif 

如果数据包含逗号,例如Post001 更改为值 Post001, <<note the comma in the data>>

然后:-

D/CSV_DATA2: {PostDataLocal},1,Post001{COMMA} <<note the comma in the data>>,2,Post002,3 ....
  • 这个额外的解决方案还修复了第一个中的一个小错误,即标题和数据之间省略了一些分隔逗号。

关于android - 如何将房间数据库导出为 .CSV,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73179816/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com