Экспорт базы данных комнат в файл csv в android

Существует множество руководств по экспорту базы данных SQLite в файл csv, но их недостаточно для экспорта из базы данных комнаты.

Используя ссылку на экспорт sqlite, Экспорт базы данных SQLite в файл csv в android анализирует каждый столбец строки вручную для помещения. Вот мой код:

     @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)
      }

Есть ли другой способ экспортировать CSV. Даже в комнате не получается получить имя столбца таблицы прагматично, поэтому невозможно создать динамически общую логику для всей таблицы.

база номеров - это база данных sqlite - нет никакой разницы

pskink 27.06.2018 07:40

Вы можете использовать библиотеку Jackson CSV для сопоставления классов комнат с файлами.

OneCricketeer 27.06.2018 07:41
7
2
10 520
3

Ответы 3

Я попытался перебрать большую базу данных Room двумя способами:

1- Получите Cursor и повторите его:

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- Используйте PagedList, чтобы получить количество элементов pageSize сразу и обработать. Затем запросите другую страницу и обработайте:

@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)
}

Теперь функция выше getCategories() вернет pagedList внутри Flowable или LiveData. Поскольку мы установили setEnablePlaceholders(true), pagedList.size будет показывать весь размер, даже если его нет в памяти. Итак, если pageSize равен 50, а размер всех данных равен 1000, pagedList.size вернет 1000, но большинство из них будут нулевыми. Чтобы запросить следующую страницу и обработать:

// 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
     }
}

Заключение: в подходе PagedList вы можете получать тысячи строк одновременно и обрабатывать, тогда как в подходе Cursor вы выполняете итерацию строка за строкой. Я обнаружил, что PagedList нестабилен, когда pageSize> 3000. Иногда он не возвращает страницу. Поэтому я использовал Cursor. Для перебора (и обработки) 900 тыс. Строк в обоих подходах на телефоне Android 8 требуется примерно 5 минут.

Вопрос об экспорте базы данных, а не о том, КАК ИСПОЛЬЗОВАТЬ БИБЛИОТЕКУ СТРАНИЦЫ!

buzzingsilently 19.01.2019 16:23

Речь идет об извлечении базы данных путем итерации над таблицами. Потому что вы можете преобразовать данные при экспорте. Экспорт - это не только сброс базы данных и создание из нее файла со всем, что находится внутри.

Jemshit Iskenderov 19.01.2019 16:29

Чтобы экспортировать данные из базы данных комнат в файл mydb.sqlite и сохранить их во внешнем хранилище, выполните следующие действия.

  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()
                    }
                }
            }
       }

Попробуй это
получить данные столбца из курсора

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

Другие вопросы по теме

Похожие вопросы