Skip to content

Commit 7d3cbc3

Browse files
committed
load --replace option, closes #6
1 parent 69d3e52 commit 7d3cbc3

File tree

3 files changed

+42
-7
lines changed

3 files changed

+42
-7
lines changed

README.md

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,25 @@ Tools for dumping/loading a SQLite database to diffable directory structure
1212

1313
## Dumping a database
1414

15-
Given a SQLite database called `fixtures.db` containing a table `facetable`, the following will dump out that table to the `out/` directory:
15+
Given a SQLite database called `fixtures.db` containing a table `facetable`, the following will dump out that table to the `dump/` directory:
1616

17-
sqlite-diffable dump fixtures.db out/ facetable
17+
sqlite-diffable dump fixtures.db dump/ facetable
1818

1919
To dump out every table in that database, use `--all`:
2020

21-
sqlite-diffable dump fixtures.db out/ --all
21+
sqlite-diffable dump fixtures.db dump/ --all
2222

2323
## Loading a database
2424

2525
To load a previously dumped database, run the following:
2626

27-
sqlite-diffable load restored.db out/
27+
sqlite-diffable load restored.db dump/
28+
29+
This will show an error if any of the tables that are being restored already exist in the database file.
30+
31+
You can replace those tables (dropping them before restoring them) using the `--replace` option:
32+
33+
sqlite-diffable load restored.db dump/ --replace
2834

2935
## Demo
3036

sqlite_diffable/cli.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import json
33
import pathlib
44
import sqlite_utils
5+
import sqlite3
56

67

78
@click.group()
@@ -72,13 +73,14 @@ def dump(dbpath, output, tables, all):
7273
"directory",
7374
type=click.Path(file_okay=False, dir_okay=True),
7475
)
75-
def load(dbpath, directory):
76+
@click.option("--replace", is_flag=True, help="Replace tables if they exist already")
77+
def load(dbpath, directory, replace):
7678
"""
7779
Load flat files from a directory into a SQLite database
7880
7981
Usage:
8082
81-
sqlite-diffable load my.db output/
83+
sqlite-diffable load my.db dump-location/
8284
"""
8385
db = sqlite_utils.Database(dbpath)
8486
directory = pathlib.Path(directory)
@@ -87,7 +89,15 @@ def load(dbpath, directory):
8789
info = json.loads(metadata.read_text())
8890
columns = info["columns"]
8991
schema = info["schema"]
90-
db.execute(schema)
92+
if db[info["name"]].exists() and replace:
93+
db[info["name"]].drop()
94+
try:
95+
db.execute(schema)
96+
except sqlite3.OperationalError as ex:
97+
msg = str(ex)
98+
if "already exists" in msg:
99+
msg += "\n\nUse the --replace option to over-write existing tables"
100+
raise click.ClickException(msg)
91101
# Now insert the rows
92102
ndjson = metadata.parent / metadata.stem.replace(".metadata", ".ndjson")
93103
rows = (

tests/test_dump.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,22 @@ def test_load(two_tables_db, tmpdir):
5757
assert list(db["second_table"].rows) == [
5858
{"id": 1, "name": "Cleo"},
5959
]
60+
# Running load a second time should error
61+
result3 = CliRunner().invoke(cli.cli, ["load", str(restore_db), str(output_dir)])
62+
assert result3.exit_code == 1
63+
assert result3.output == (
64+
"Error: table [second_table] already exists\n\n"
65+
"Use the --replace option to over-write existing tables\n"
66+
)
67+
# Using --replace should work correctly
68+
(output_dir / "one_table.ndjson").write_text(
69+
'[1, "Stacey"]\n[2, "Tilda"]\n', "utf-8"
70+
)
71+
result4 = CliRunner().invoke(
72+
cli.cli, ["load", str(restore_db), str(output_dir), "--replace"]
73+
)
74+
assert result4.exit_code == 0
75+
assert list(db["one_table"].rows) == [
76+
{"id": 1, "name": "Stacey"},
77+
{"id": 2, "name": "Tilda"},
78+
]

0 commit comments

Comments
 (0)