Skip to content

Commit cbfe592

Browse files
authored
Merge pull request #2430 from opensafely-core/KatieB5/populate-development-dbs-with-test-fixture-data
Populate development dbs with test fixture data
2 parents c098802 + 7ab10ad commit cbfe592

File tree

4 files changed

+181
-5
lines changed

4 files changed

+181
-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: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,42 @@ 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+
261+
if [[ -z "${DATABASE_URL:-}" ]]; then
262+
CORE_DB_PATH="db.sqlite3"
263+
else
264+
CORE_DB_PATH="${DATABASE_URL/sqlite:\/\/\//}"
265+
fi
266+
echo "Nuclear option enabled: moving $CORE_DB_PATH to $CORE_DB_PATH.backup"
267+
268+
mv "$CORE_DB_PATH" "$CORE_DB_PATH.backup"
269+
270+
# Set up or update the local dev environment:
271+
# - Recreates core DB and applies migrations
272+
just dev-setup
273+
274+
# Run custom command to:
275+
# - Load CodingSystemReleases needed for the test data fixtures
276+
# - Remove old coding system release dbs (with confirmation)
277+
# - Create and migrate new coding system release dbs
278+
# - Load test data into coding system release dbs
279+
$BIN/python manage.py setup_local_dev_databases
280+
else
281+
echo "Skipping creation of a new empty core db.sqlite3. Run with 'nuclear' parameter to enable."
282+
fi
283+
284+
285+
250286
# build docker image env=dev|prod
251287
docker-build env="dev": _env
252288
{{ just_executable() }} docker/build {{ env }}
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
import sys
2+
3+
from django.core.management import BaseCommand, call_command
4+
5+
from coding_systems.versioning.models import (
6+
CodingSystemRelease,
7+
build_db_path,
8+
update_coding_system_database_connections,
9+
)
10+
from opencodelists import settings
11+
from opencodelists.tests.fixtures import build_fixtures
12+
13+
14+
class Command(BaseCommand):
15+
help = """Populates local opencodelists dbs with test fixture data:
16+
Loads the CodingSystemReleases needed for the snomed and dmd
17+
fixtures into the Core db (you will be prompted for consent
18+
to do this), deletes existing test coding system release dbs,
19+
creates new coding system release dbs, populates these with
20+
test fixture data, instantiates a universe of fixture
21+
objects, and creates a superuser. Running this command
22+
directly is not recommended, instead use `just
23+
build-dbs-for-local-development`"""
24+
25+
def handle(self, *args, **options):
26+
if not settings.DEBUG:
27+
self.stderr.write(
28+
"This management command will not run in a production environment."
29+
)
30+
sys.exit(1)
31+
32+
load_versioning_fixture_answer = input(
33+
"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)"
34+
)
35+
36+
if load_versioning_fixture_answer == "n":
37+
return
38+
39+
call_command(
40+
"loaddata",
41+
"coding_systems/versioning/fixtures/coding_system_releases.json",
42+
)
43+
44+
self.stdout.write("Deleting local coding system release dbs...")
45+
for coding_system_release in CodingSystemRelease.objects.all():
46+
db_path = build_db_path(coding_system_release)
47+
if db_path.exists():
48+
db_path.unlink()
49+
self.stdout.write(f"{str(db_path)} has been deleted")
50+
51+
self.stdout.write(
52+
"Migrating coding system release dbs and populating them with test fixture data"
53+
)
54+
55+
update_coding_system_database_connections()
56+
57+
# migrate snomedct test db and load test fixtures
58+
call_command("migrate", "snomedct", database="snomedct_test_20200101")
59+
60+
call_command(
61+
"loaddata",
62+
"coding_systems/snomedct/fixtures/core-model-components.snomedct_test_20200101.json",
63+
database="snomedct_test_20200101",
64+
)
65+
66+
call_command(
67+
"loaddata",
68+
"coding_systems/snomedct/fixtures/tennis-elbow.snomedct_test_20200101.json",
69+
database="snomedct_test_20200101",
70+
)
71+
72+
call_command(
73+
"loaddata",
74+
"coding_systems/snomedct/fixtures/tennis-toe.snomedct_test_20200101.json",
75+
database="snomedct_test_20200101",
76+
)
77+
78+
# migrate dmd test db and load test fixture
79+
call_command("migrate", "dmd", database="dmd_test_20200101")
80+
81+
call_command(
82+
"loaddata",
83+
"coding_systems/dmd/fixtures/asthma-medication.dmd_test_20200101.json",
84+
database="dmd_test_20200101",
85+
)
86+
87+
# migrate bnf test db and load test fixture
88+
call_command("migrate", "bnf", database="bnf_test_20200101")
89+
90+
call_command(
91+
"loaddata",
92+
"coding_systems/bnf/fixtures/asthma.bnf_test_20200101.json",
93+
database="bnf_test_20200101",
94+
)
95+
96+
# migrate icd10 test db and load test fixture
97+
call_command("migrate", "icd10", database="icd10_test_20200101")
98+
call_command(
99+
"loaddata",
100+
"coding_systems/icd10/fixtures/icd10.icd10_test_20200101.json",
101+
database="icd10_test_20200101",
102+
)
103+
104+
# instantiate the test data universe
105+
build_fixtures()
106+
107+
call_command(
108+
"createsuperuser",
109+
no_input=True,
110+
username="localdev",
111+
email="localdev@example.com",
112+
)
113+
114+
self.stdout.write(
115+
"Local setup complete! You can now:\n"
116+
" - Log in as `localdev`\n"
117+
" - Search for 'arthritis', 'tennis', and 'elbow'\n"
118+
" - Build codelists with the concepts returned from these searches (see /opencodelists/opencodelists/tests/fixtures.py for more info)\n"
119+
" - View a BNF codelist, a minimal codelist, and a new-style SNOMED CT codelist"
120+
)
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import pytest
2+
from django.core.management import call_command
3+
4+
# from opencodelists.management.commands import setup_local_dev_databases
5+
from opencodelists import settings
6+
7+
8+
def test_setup_local_dev_databases_exits_early_when_in_prod_environment(monkeypatch):
9+
monkeypatch.setattr(settings, "DEBUG", False)
10+
11+
with pytest.raises(SystemExit) as error:
12+
call_command("setup_local_dev_databases")
13+
14+
assert error.value.code == 1

0 commit comments

Comments
 (0)