Exporting an SQLite3 database to a directory of CSV files
Recently I was working with a dataset I acquired for my PhD, and to pre-process said dataset into something more sensible I imported it into an SQLite3 database. Once I was finished processing it, I then needed to export it again into regular CSV files so that I could do other things, such as plot it with GNUPlot, or import it into InfluxDB (more on InfluxDB in a later post).
With the help of Stack Overflow and the SQLite3 man page, this didn't prove to be too difficult. To export a single SQLite3 table to a CSV file, you do this:
sqlite3 -bail -header -csv "bobsrockets.sqlite3" "SELECT * FROM 'table_name';" >"path/to/output_file.csv";
This is great for a single table, but what if we want to export all the tables? Well, we can iterate over all the tables in an SQLite3 database like so:
while read table_name; do
echo "Exporting ${table_name}";
# Do stuff
done < <(sqlite3 "bobsrockets.sqlite3" ".tables");
If we combine this with the previous snippet, we can export all the tables like so:
while read table_name; do
log "Exporting ${table_name}";
sqlite3 -bail -header -csv "bobsrockets.sqlite3" "SELECT * FROM '${table_name}';" >"${table_name}.csv";
done < <(sqlite3 "bobsrockets.sqlite3" ".tables");
Cool! We can make it even better with some simple improvements though:
- It's a pain to have to edit the script every time we want to change the database we're exporting
- It would be nice to be able to specify the output directory without editing the script too
Satisfying both of these points isn't particularly challenging. 10 minutes of fiddling got this the final completed script:
#!/usr/bin/env bash
set -e; # Don't allow errors
show_usage() {
echo -e "Usage:";
echo -e "\t./sqlite2csv.sh {db_filename} {output_dir}";
}
log() {
echo -e "[ $(date +"%F %T") ] ${@}";
}
###############################################################################
db_filename="${1}";
output_dir="${2}";
if [ -z "${db_filename}" ]; then
echo "Error: No database filename specified.";
show_usage; exit;
fi
if [ -z "${output_dir}" ]; then
echo "Error: No output directory specified.";
show_usage; exit;
fi
if [ ! -d "${output_dir}" ]; then
mkdir -p "${output_dir}";
fi
log "Output directory is ${output_dir}";
while read table_name; do
log "Exporting ${table_name}";
sqlite3 -bail -header -csv "${db_filename}" "SELECT * FROM '${table_name}';" >"${output_dir}/${table_name}.csv";
done < <(sqlite3 "${db_filename}" ".tables");
log "Complete!";
Found this useful? Comment below!