Exporting Room Database to csv file in android

陌路散爱 提交于 2019-12-12 13:12:59

问题


There are many tutorials available for exporting SQLite database to csv file but not enough stuff for exporting from room database.

Using sqlite export reference Exporting SQLite Database to csv file in android parsing each column of row manually for room. Following is my code:

     @Dao
     interface CategoryDao {
         @Query("SELECT * FROM Category")
         fun getAllCategory(): List<Category>
     }

//   Export csv logic

      val categoryList = categoryDao.getAllCategory()
      val csvWrite = CSVWriter(FileWriter(file))

      for (item in categoryList) {
         val arrStr = arrayOf<String>(item.categoryId, item.categoryName)
         csvWrite.writeNext(arrStr)
      }

Is there any other way to export csv. Even in room not getting columns name of table pragmatically so not able to create dynamically common logic for all table.


回答1:


This might be Answer that you are searching.

Link: https://stackoverflow.com/a/49133574/9994604

There is also a Manual way to do it. Export Database,

Link: https://stackoverflow.com/a/6542214/9994604

Open in Sqlite Browser: https://sqlitebrowser.org (Free)

Export in CSV/JSON,SQL whichever you like.




回答2:


Try this
get Column data from Cursor

@Query("SELECT * FROM Category")
Cursor getAllCategory();



回答3:


There are two ways i have tried to iterate over large Room database:

1- Get Cursor and iterate over that:

import android.database.Cursor
...
@Query("SELECT * FROM Category")
fun getAllCategory(): Cursor<Category>
...
val success = cursor.moveToFirst()
if (success) {
     while (!cursor.isAfterLast) {
         // Process items
         cursor.moveToNext()
     }
} else {
    // Empty
}
cursor.close()

2- Use PagedList to get pageSize amount of items at once and process. Then query another page and process:

@Query("SELECT * FROM Category")
fun getAllCategory(): DataSource.Factory<Int, Category>

// Here i will return Flowable. You can return LiveData with 'LivePagedListBuilder'
fun getCategories(pageSize: Int): Flowable<PagedList<Category>> {
        val config = PagedList.Config.Builder()
                .setPageSize(pageSize)
                .setPrefetchDistance(pageSize / 4)
                .setEnablePlaceholders(true)
                .setInitialLoadSizeHint(pageSize)
                .build()
        return RxPagedListBuilder(categoryDao.getAllCategory(), config)
                .buildFlowable(BackpressureStrategy.BUFFER)
}

Now above getCategories() function will return pagedList inside Flowable or LiveData. Since we have set setEnablePlaceholders(true), pagedList.size will show the whole size even if it is not in memory. So, if pageSize is 50 and all data size is 1000, pagedList.size will return 1000, but most of them will be null. To query next page and process:

// Callback is triggered when next page is loaded
pagedList.addWeakCallback(pagedList.snapshot(), object : PagedList.Callback() {
    override fun onChanged(position: Int, count: Int) {
        for (index in position until (position + count)) {
            if (index == (position + count - 1)) {
                if (index < (pagedList.size - 1)) 
                    pagedList.loadAround(index + 1)
                else{ 
                    // Last item is processed.
                }
            } else
                processCurrentValue(index, pagedList[index]!!)
        }
    }
    override fun onInserted(position: Int, count: Int) {
        // You better not change database while iterating over it 
    }    
    override fun onRemoved(position: Int, count: Int) {
        // You better not change database while iterating over it
    }
})

// Start to iterate and query next page when item is null.
for (index in 0 until pagedList.size) {
     if (pagedList[index] != null) {
            processCurrentValue(index, pagedList[index]!!)
     } else {
            // Query next page
            pagedList.loadAround(index)
            break
     }
}

Conclusion: In PagedList approach, you can get thousands of rows at once and process, while in Cursor approach you iterate row by row. I found PagedList unstable when pageSize > 3000. It does not return the page sometimes. So i used Cursor. It takes roughly about 5 minutes to iterate over (and process) 900k rows on both approaches on Android 8 phone.




回答4:


To Export the Room Database data into mydb.sqlite file and store into External storage, follow the steps.

  fun exportDatabase(){
      val sd = Environment.getExternalStorageDirectory()

      // Get the Room database storage path using SupportSQLiteOpenHelper 
      AppDatabase.getDatabase(applicationContext)!!.openHelper.writableDatabase.path

            if (sd.canWrite()) {
                val currentDBPath = AppDatabase.getDatabase(applicationContext)!!.openHelper.writableDatabase.path
                val backupDBPath = "mydb.sqlite"      //you can modify the file type you need to export
                val currentDB = File(currentDBPath)
                val backupDB = File(sd, backupDBPath)
                if (currentDB.exists()) {
                    try {
                        val src = FileInputStream(currentDB).channel
                        val dst = FileOutputStream(backupDB).channel
                        dst.transferFrom(src, 0, src.size())
                        src.close()
                        dst.close()
                    } catch (e: IOException) {
                        e.printStackTrace()
                    }
                }
            }
       }


来源:https://stackoverflow.com/questions/51055184/exporting-room-database-to-csv-file-in-android

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!