【问题标题】:How to export Room Database to .CSV如何将房间数据库导出为 .CSV
【发布时间】:2023-01-13 00:09:33
【问题描述】:

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

【问题讨论】:

    标签: android database csv kotlin android-room


    【解决方案1】:

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

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

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

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

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

    如果有多个表,则必须区分表的数据。

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

    然而,作为基于的示例:-

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

    • PostDataLocal(列见下文)
    • 本地组数据
    • AdminDataLocal
      • 现有答案已针对该示例进行了调整

    然后:-

    @Dao 注释接口(即 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 :-
    	$sb")
    
    }
    

    然后在一个活动中(dao 已被实例化)以下内容:-

    createCSV() 
    

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

    PostDataLocal

    组数据本地

    AdminDataLocal

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

    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, &lt;&lt;note the comma in the data&gt;&gt;

    然后 :-

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

    【讨论】:

    • 这正是我需要的答案,这真的很有帮助上帝保佑你!!
    【解决方案2】:

    从房间获取所有数据作为列表并使用此库 https://github.com/doyaaaaaken/kotlin-csv

    【讨论】:

      猜你喜欢
      • 2018-12-05
      • 1970-01-01
      • 1970-01-01
      • 2019-03-19
      • 2018-09-05
      • 2018-08-29
      • 2016-02-12
      • 2013-07-02
      • 2013-12-20
      相关资源
      最近更新 更多