Reputation: 5
I have many tables in my database in the app. During the app use, these tables are created by the user and also their names.
I would like to export all tables, each one to a single .CSV file with the table's name.
For example, I have 3 tables named 1, 2 and 3. I would like to export and them create files 1.csv, 2.csv and 3.csv.
I really appreciate some help, because I could not find any answer in the web.
I am using some classes called CSVReader and CSVWriter, which are very popular.
Here in my method to export. It does not show any error, but no file is exported:
public void exportTables (View view) {
File dbFile = getDatabasePath("database.db");
Banco dbhelper = new Banco(getApplicationContext());
File exportDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
if (!exportDir.exists()) {
exportDir.mkdirs();
}
File file = new File(exportDir, tableName +".csv");
try {
file.createNewFile();
CSVWriter csvWriter = new CSVWriter(new FileWriter(file));
SQLiteDatabase db = dbhelper.getReadableDatabase();
Cursor curCSV = db.rawQuery("SELECT * FROM sqlite_master WHERE type='table' AND name NOT LIKE 'android_metadata' AND name NOT LIKE 'sqlite_sequence'", null);
csvWriter.writeNext(curCSV.getColumnNames());
while(curCSV.moveToNext()) {
// Table columns
String arrStr[] ={curCSV.getString(0),curCSV.getString(1)};
csvWriter.writeNext(arrStr);
}
csvWriter.close();
curCSV.close();
}
catch(Exception sqlEx) {
Log.e("MainActivity", sqlEx.getMessage(), sqlEx);
}
Toast.makeText(this, "FILE EXPORTED WITH SUCCESS!", Toast.LENGTH_SHORT).show();
}
Upvotes: 0
Views: 1832
Reputation: 9766
This actually a 2 steps process:
1 - List table names
Your first query
SELECT *
FROM sqlite_master
WHERE type='table'
AND name NOT LIKE 'android_metadata'
AND name NOT LIKE 'sqlite_sequence'
returns a list of tables and looks like this
type | name | tbl_name | rootpage | sql |
------+--------+----------+----------+------------------+
table | table1 | table1 | 2 | CREATE TABLE ... |
table | table2 | table2 | 2 | CREATE TABLE ... |
table | table3 | table3 | 2 | CREATE TABLE ... |
You could simply return the names instead of all the columns
SELECT name
FROM sqlite_master
WHERE type='table'
AND name NOT LIKE 'android_metadata'
AND name NOT LIKE 'sqlite_sequence'
You need to read each row to get table names
2 - Then for each table you need create a file and query the table, ex:
SELECT * FROM table1
Then stick these in your file
CODE:
I did not test that code but you should be able to make it work:
This first method will list the table names
private static List<String> listTables(SQLiteDatabase db) {
List<String> tableNames = new ArrayList<>();
Cursor tableListCursor = db.rawQuery("SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'android_metadata' AND name NOT LIKE 'sqlite_sequence'", null);
while(tableListCursor.moveToNext()) {
// get the name of the table
tableNames.add(tableListCursor.getString(0));
}
tableListCursor.close();
return tableNames;
}
This second method will dump a table to a file
private static void dumpTableToCsvFile(SQLiteDatabase db, String tableName) {
try {
// Query the data in the table
Cursor cursor = db.rawQuery("SELECT * FROM " + tableName, null);
File file = new File(exportDir, tableName +".csv");
file.createNewFile();
CSVWriter csvWriter = new CSVWriter(new FileWriter(file));
// Write the table data to the file
csvWriter.writeNext(cursor.getColumnNames());
while(cursor.moveToNext()) {
String arrStr[] = { cursor.getString(0), cursor.getString(1) };
csvWriter.writeNext(arrStr);
}
// close cursor and writer
cursor.close();
csvWriter.close();
} catch (IOException e) {
// handle exception
}
}
And you use them this way:
SQLiteDatabase db = dbhelper.getReadableDatabase();
List<String> tableNames = listTables(db);
for(String tableName : tableNames) {
dumpTableToCsvFile(db, tableName);
}
Upvotes: 1