Commit d6d3c40d authored by Paulo V C Medeiros's avatar Paulo V C Medeiros
Browse files

Initial commit. Add merge_using_attach.py

parents
#!/usr/bin/env python3
import argparse
import shutil
import sqlite3
from pathlib import Path
import logging
def merge_sqlite_dbs(input_files, output_file, overwrite):
logger = logging.getLogger(__name__)
if len(input_files) == 0:
logger.warning("No input files passed. Doing nothing.")
return
# Forbid out file to be listed as input
if output_file in input_files:
raise ValueError("Output file '%s' is also listed as input" % (output_file))
# Overwrite or raise error if out file exists
if output_file.is_file():
if overwrite:
Path.unlink(output_file)
else:
raise FileExistsError(
"'%s'. Please use '--overwrite' if you wish the file to be overwritten"
% (output_file)
)
elif output_file.exists():
raise FileExistsError(
"Path '%s' exists and is not a regular file" % s(output_file)
)
###############
# Merge files #
###############
# (a) Initialise output file with the contents of the first input
shutil.copy(input_files[0], output_file)
# (b) Loop over remaining input files and add their contents into output_file
with sqlite3.connect(str(output_file.resolve())) as conn:
cur = conn.cursor()
cur.execute("PRAGMA synchronous = OFF;")
cur.execute("PRAGMA TEMP_STORE = MEMORY")
for db in input_files[1:]:
# Start from 1: Skip first input (already added)
logger.debug("Copying contents of file '%s':", db)
cur.execute("ATTACH '%s' AS current_db;" % (db.resolve()))
# Loop through each one of current_db's tables and add their data into
# the corresponding out_db's tables
cur.execute("SELECT name FROM current_db.sqlite_master WHERE type='table';")
all_tables = cur.fetchall()
for table in all_tables:
# Append data assuming same columns in the same position
logger.debug(" > '%s' table", table)
sql = "INSERT INTO {0} SELECT * FROM current_db.[{0}];".format(table[0])
cur.execute(sql)
conn.commit()
cur.execute("DETACH current_db;")
cur.close()
if __name__ == "__main__":
parser = argparse.ArgumentParser(
prog="merge_sqlite_dbs", formatter_class=argparse.ArgumentDefaultsHelpFormatter
)
parser.add_argument("input_files", nargs="*", type=Path)
parser.add_argument("--output_file", "-o", type=Path, default=Path("out.db"))
parser.add_argument("--overwrite", action="store_true")
parser.add_argument(
"-loglevel",
default="info",
choices=["critical", "error", "warning", "info", "debug", "notset"],
)
args = parser.parse_args()
logging.basicConfig(level=logging.getLevelName(args.loglevel.upper()))
merge_sqlite_dbs(args.input_files, args.output_file, args.overwrite)
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment