Skip to content

Instantly share code, notes, and snippets.

@kazlauskis
Created September 8, 2016 13:26
Show Gist options
  • Star 12 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save kazlauskis/1d0bdb9efb3b1bb1e76d48aa368f3a64 to your computer and use it in GitHub Desktop.
Save kazlauskis/1d0bdb9efb3b1bb1e76d48aa368f3a64 to your computer and use it in GitHub Desktop.
Transforms MS Access MDB file to sqlite database using mdbtools
#!/bin/bash
# Inspired by
# https://www.codeenigma.com/community/blog/using-mdbtools-nix-convert-microsoft-access-mysql
# USAGE
# Rename your MDB file to migration-export.mdb
# run ./mdb2sqlite.sh migration-export.mdb
# wait and wait a bit longer...
mdb-schema migration-export.mdb sqlite > schema.sql
mkdir sqlite
mkdir sql
for i in $( mdb-tables migration-export.mdb ); do echo $i ; mdb-export -D "%Y-%m-%d %H:%M:%S" -H -I sqlite migration-export.mdb $i > sql/$i.sql; done
mv schema.sql sqlite
mv sql sqlite
cd sqlite
cat schema.sql | sqlite3 db.sqlite3
for f in sql/* ; do echo $f && cat $f | sqlite3 db.sqlite3; done
@phiresky
Copy link

For a large speed increase, replace the last line with

for f in sql/* ; do echo $f && (echo 'BEGIN;'; cat $f; echo 'COMMIT;') | sqlite3 db.sqlite3; done

@jsgalan
Copy link

jsgalan commented Jul 19, 2020

thanks!

@vschmidt
Copy link

vschmidt commented Dec 1, 2021

Thank you for that. I've improved the script, now it accepts parameters and removes files after running:

test -f $2 && rm $2

mdb-schema $1 sqlite > schema.sql
mkdir sql
for i in $( mdb-tables $1 ); do mdb-export -D "%Y-%m-%d %H:%M:%S" -H -I sqlite $1 $i > sql/$i.sql; done
cat schema.sql | sqlite3 $2
for f in sql/* ; do (echo 'BEGIN;'; cat $f; echo 'COMMIT;') | sqlite3 $2; done

rm -R sql
rm schema.sql
rm $1

To run:

mdb2sqlite.sh <input_file.mdb> <output_file.sqlite3>

@kristopolous
Copy link

kristopolous commented Oct 10, 2022

Here's a cleanup I did.

  • You can pass the command line argument for the db as you probably thought you ought to
  • it creates a unique working directory using timestamps and logical naming
  • you can swap out the sqlite executable name with the sqlite variable at the beginning
  • it has the optimizations by @phiresky
  • it's side-effect free from multiple executions
  • everything is localized to the file name so it's parallelizable as well
#!/bin/bash
# Inspired by 
# https://www.codeenigma.com/community/blog/using-mdbtools-nix-convert-microsoft-access-mysql

# USAGE
# Rename your MDB file to migration-export.mdb 
# run ./mdb2sqlite.sh migration-export.mdb
# wait and wait a bit longer...

now=$(date +%s)
sqlite=sqlite3
fname=$1
sql=${fname/mdb/sqlite}
schema=${fname/mdb/schema}
dir=${fname/.mdb/}-$now

mkdir $dir

mdb-schema $fname sqlite > $dir/$schema

for i in $( mdb-tables $fname ); do 
  echo $i  
  mdb-export -D "%Y-%m-%d %H:%M:%S" -H -I sqlite $fname $i > $dir/$i.sql
done

< $dir/$schema $sqlite $sql

for f in $dir/*.sql ; do 
  echo $f 
  (echo 'BEGIN;'; cat $f; echo 'COMMIT;') | $sqlite $sql
done
echo "Using $dir"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment