Skip to content

Commit c4417ca

Browse files
KatieB5Jongmassey
andcommitted
Populate development dbs with test fixture data
Closes #2313. It was suggested in #2313 that using existing test fixture data as dummy data for local development purposes may provide a good alternative to using a copy of prod databases. The approach taken here shows one way to populate local dbs with test fixture data, based on a comment on the original issue, and a spike (#2407). Co-authored-by: Jon Massey <jon.massey@thedatalab.org>
1 parent 5e8cc87 commit c4417ca

File tree

3 files changed

+149
-5
lines changed

3 files changed

+149
-5
lines changed

coding_systems/versioning/models.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -76,13 +76,19 @@ def update_coding_system_database_connections():
7676
for coding_system_release in CodingSystemRelease.objects.all():
7777
if not CODING_SYSTEMS[coding_system_release.coding_system].has_database:
7878
continue
79-
db_path = (
80-
settings.CODING_SYSTEMS_DATABASE_DIR
81-
/ coding_system_release.coding_system
82-
/ f"{coding_system_release.database_alias}.sqlite3"
83-
)
79+
db_path = build_db_path(coding_system_release)
8480
database_dict = {
8581
**connections.databases[DEFAULT_DB_ALIAS],
8682
**dj_database_url.parse(f"sqlite:///{db_path}"),
8783
}
8884
connections.databases[coding_system_release.database_alias] = database_dict
85+
86+
87+
def build_db_path(coding_system_release):
88+
db_path = (
89+
settings.CODING_SYSTEMS_DATABASE_DIR
90+
/ coding_system_release.coding_system
91+
/ f"{coding_system_release.database_alias}.sqlite3"
92+
)
93+
94+
return db_path

justfile

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,41 @@ assets-test: assets-install
247247
npm run test:coverage
248248

249249

250+
# Build a lightweight local development setup using test fixture data.
251+
build-dbs-for-local-development nuclear="":
252+
#!/usr/bin/env bash
253+
set -euo pipefail
254+
255+
# WARNING: Passing 'nuclear' to this just recipe will create a
256+
# backup copy of your current local db, if it exists, then create a
257+
# new empty core `db.sqlite3` in the root directory of your
258+
# opencodelists project folder.
259+
if [ -n "{{ nuclear }}" ]; then
260+
echo "Nuclear option enabled: deleting db.sqlite3"
261+
262+
if [[ -z "${DATABASE_URL:-}" ]]; then
263+
CORE_DB_PATH="db.sqlite3"
264+
else
265+
CORE_DB_PATH="${DATABASE_URL/sqlite:\/\/\//}"
266+
fi
267+
mv "$CORE_DB_PATH" "$CORE_DB_PATH.backup"
268+
269+
# Set up or update the local dev environment:
270+
# - Recreates core DB and applies migrations
271+
just dev-setup
272+
273+
# Run custom command to:
274+
# - Load CodingSystemReleases needed for the test data fixtures
275+
# - Remove old coding system release dbs (with confirmation)
276+
# - Create and migrate new coding system release dbs
277+
# - Load test data into coding system release dbs
278+
$BIN/python manage.py setup_local_dev_databases
279+
else
280+
echo "Skipping db.sqlite3 deletion. Run with 'nuclear' parameter to enable."
281+
fi
282+
283+
284+
250285
# build docker image env=dev|prod
251286
docker-build env="dev": _env
252287
{{ just_executable() }} docker/build {{ env }}
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
from django.core.management import BaseCommand, call_command
2+
3+
from coding_systems.versioning.models import (
4+
CodingSystemRelease,
5+
build_db_path,
6+
update_coding_system_database_connections,
7+
)
8+
from opencodelists.tests.fixtures import build_fixtures
9+
10+
11+
class Command(BaseCommand):
12+
help = """Populates local opencodelists dbs with test fixture data: Loads the CodingSystemReleases needed for the snomed and dmd fixtures into the Core db (you will be prompted for consent to do this), deletes existing test coding system release dbs, creates new coding system release dbs, populates these with test fixture data, instantiates a universe of fixture objects, and creates a superuser. Running this command directly is not recommended, instead use `just build-dbs-for-local-development`"""
13+
14+
def handle(self, *args, **options):
15+
load_versioning_fixture_answer = input(
16+
"Running this command will load the CodingSystemReleases needed for the snomed and dmd test fixtures, into the Core db. Any local test coding system release dbs will then be deleted and recreated. Do you want to proceed? (Y/n)"
17+
)
18+
19+
if load_versioning_fixture_answer == "n":
20+
return
21+
22+
call_command(
23+
"loaddata",
24+
"coding_systems/versioning/fixtures/coding_system_releases.json",
25+
)
26+
27+
self.stdout.write("Deleting local coding system release dbs...")
28+
for coding_system_release in CodingSystemRelease.objects.all():
29+
db_path = build_db_path(coding_system_release)
30+
if db_path.exists():
31+
db_path.unlink()
32+
self.stdout.write(f"{str(db_path)} has been deleted")
33+
34+
self.stdout.write(
35+
"Migrating coding system release dbs and populating them with test fixture data"
36+
)
37+
38+
update_coding_system_database_connections()
39+
40+
# migrate snomedct test db and load test fixtures
41+
call_command("migrate", "snomedct", database="snomedct_test_20200101")
42+
43+
call_command(
44+
"loaddata",
45+
"coding_systems/snomedct/fixtures/core-model-components.snomedct_test_20200101.json",
46+
database="snomedct_test_20200101",
47+
)
48+
49+
call_command(
50+
"loaddata",
51+
"coding_systems/snomedct/fixtures/tennis-elbow.snomedct_test_20200101.json",
52+
database="snomedct_test_20200101",
53+
)
54+
55+
call_command(
56+
"loaddata",
57+
"coding_systems/snomedct/fixtures/tennis-toe.snomedct_test_20200101.json",
58+
database="snomedct_test_20200101",
59+
)
60+
61+
# migrate dmd test db and load test fixture
62+
call_command("migrate", "dmd", database="dmd_test_20200101")
63+
64+
call_command(
65+
"loaddata",
66+
"coding_systems/dmd/fixtures/asthma-medication.dmd_test_20200101.json",
67+
database="dmd_test_20200101",
68+
)
69+
70+
# migrate bnf test db and load test fixture
71+
call_command("migrate", "bnf", database="bnf_test_20200101")
72+
73+
call_command(
74+
"loaddata",
75+
"coding_systems/bnf/fixtures/asthma.bnf_test_20200101.json",
76+
database="bnf_test_20200101",
77+
)
78+
79+
# migrate icd10 test db and load test fixture
80+
call_command("migrate", "icd10", database="icd10_test_20200101")
81+
call_command(
82+
"loaddata",
83+
"coding_systems/icd10/fixtures/icd10.icd10_test_20200101.json",
84+
database="icd10_test_20200101",
85+
)
86+
87+
# instantiate the test data universe
88+
build_fixtures()
89+
90+
call_command(
91+
"createsuperuser",
92+
no_input=True,
93+
username="localdev",
94+
email="localdev@example.com",
95+
)
96+
97+
self.stdout.write(
98+
"Local setup complete! You can now:\n"
99+
" - Log in as `localdev`\n"
100+
" - Search for 'arthritis', 'tennis', and 'elbow'\n"
101+
" - Build codelists with the concepts returned from these searches (see /opencodelists/opencodelists/tests/fixtures.py for more info)\n"
102+
" - View a BNF codelist, a minimal codelist, and a new-style SNOMED CT codelist"
103+
)

0 commit comments

Comments
 (0)