Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 11 additions & 5 deletions coding_systems/versioning/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,19 @@ def update_coding_system_database_connections():
for coding_system_release in CodingSystemRelease.objects.all():
if not CODING_SYSTEMS[coding_system_release.coding_system].has_database:
continue
db_path = (
settings.CODING_SYSTEMS_DATABASE_DIR
/ coding_system_release.coding_system
/ f"{coding_system_release.database_alias}.sqlite3"
)
db_path = build_db_path(coding_system_release)
database_dict = {
**connections.databases[DEFAULT_DB_ALIAS],
**dj_database_url.parse(f"sqlite:///{db_path}"),
}
connections.databases[coding_system_release.database_alias] = database_dict


def build_db_path(coding_system_release):
db_path = (
settings.CODING_SYSTEMS_DATABASE_DIR
/ coding_system_release.coding_system
/ f"{coding_system_release.database_alias}.sqlite3"
)

return db_path
36 changes: 36 additions & 0 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,42 @@ assets-test: assets-install
npm run test:coverage


# Build a lightweight local development setup using test fixture data.
build-dbs-for-local-development nuclear="":
#!/usr/bin/env bash
set -euo pipefail

# WARNING: Passing 'nuclear' to this just recipe will create a
# backup copy of your current local db, if it exists, then create a
# new empty core `db.sqlite3` in the root directory of your
# opencodelists project folder.
if [ -n "{{ nuclear }}" ]; then

if [[ -z "${DATABASE_URL:-}" ]]; then
CORE_DB_PATH="db.sqlite3"
else
CORE_DB_PATH="${DATABASE_URL/sqlite:\/\/\//}"
fi
echo "Nuclear option enabled: moving $CORE_DB_PATH to $CORE_DB_PATH.backup"

mv "$CORE_DB_PATH" "$CORE_DB_PATH.backup"

# Set up or update the local dev environment:
# - Recreates core DB and applies migrations
just dev-setup

# Run custom command to:
# - Load CodingSystemReleases needed for the test data fixtures
# - Remove old coding system release dbs (with confirmation)
# - Create and migrate new coding system release dbs
# - Load test data into coding system release dbs
$BIN/python manage.py setup_local_dev_databases
else
echo "Skipping creation of a new empty core db.sqlite3. Run with 'nuclear' parameter to enable."
fi



# build docker image env=dev|prod
docker-build env="dev": _env
{{ just_executable() }} docker/build {{ env }}
Expand Down
120 changes: 120 additions & 0 deletions opencodelists/management/commands/setup_local_dev_databases.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import sys

from django.core.management import BaseCommand, call_command

from coding_systems.versioning.models import (
CodingSystemRelease,
build_db_path,
update_coding_system_database_connections,
)
from opencodelists import settings
from opencodelists.tests.fixtures import build_fixtures


class Command(BaseCommand):
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`"""

def handle(self, *args, **options):
if not settings.DEBUG:
self.stderr.write(
"This management command will not run in a production environment."
)
sys.exit(1)

load_versioning_fixture_answer = input(
"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)"
)

if load_versioning_fixture_answer == "n":
return

call_command(
"loaddata",
"coding_systems/versioning/fixtures/coding_system_releases.json",
)

self.stdout.write("Deleting local coding system release dbs...")
for coding_system_release in CodingSystemRelease.objects.all():
db_path = build_db_path(coding_system_release)
if db_path.exists():
db_path.unlink()
self.stdout.write(f"{str(db_path)} has been deleted")

self.stdout.write(
"Migrating coding system release dbs and populating them with test fixture data"
)

update_coding_system_database_connections()

# migrate snomedct test db and load test fixtures
call_command("migrate", "snomedct", database="snomedct_test_20200101")

call_command(
"loaddata",
"coding_systems/snomedct/fixtures/core-model-components.snomedct_test_20200101.json",
database="snomedct_test_20200101",
)

call_command(
"loaddata",
"coding_systems/snomedct/fixtures/tennis-elbow.snomedct_test_20200101.json",
database="snomedct_test_20200101",
)

call_command(
"loaddata",
"coding_systems/snomedct/fixtures/tennis-toe.snomedct_test_20200101.json",
database="snomedct_test_20200101",
)

# migrate dmd test db and load test fixture
call_command("migrate", "dmd", database="dmd_test_20200101")

call_command(
"loaddata",
"coding_systems/dmd/fixtures/asthma-medication.dmd_test_20200101.json",
database="dmd_test_20200101",
)

# migrate bnf test db and load test fixture
call_command("migrate", "bnf", database="bnf_test_20200101")

call_command(
"loaddata",
"coding_systems/bnf/fixtures/asthma.bnf_test_20200101.json",
database="bnf_test_20200101",
)

# migrate icd10 test db and load test fixture
call_command("migrate", "icd10", database="icd10_test_20200101")
call_command(
"loaddata",
"coding_systems/icd10/fixtures/icd10.icd10_test_20200101.json",
database="icd10_test_20200101",
)

# instantiate the test data universe
build_fixtures()

call_command(
"createsuperuser",
no_input=True,
username="localdev",
email="localdev@example.com",
)

self.stdout.write(
"Local setup complete! You can now:\n"
" - Log in as `localdev`\n"
" - Search for 'arthritis', 'tennis', and 'elbow'\n"
" - Build codelists with the concepts returned from these searches (see /opencodelists/opencodelists/tests/fixtures.py for more info)\n"
" - View a BNF codelist, a minimal codelist, and a new-style SNOMED CT codelist"
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import pytest
from django.core.management import call_command

# from opencodelists.management.commands import setup_local_dev_databases
from opencodelists import settings


def test_setup_local_dev_databases_exits_early_when_in_prod_environment(monkeypatch):
monkeypatch.setattr(settings, "DEBUG", False)

with pytest.raises(SystemExit) as error:
call_command("setup_local_dev_databases")

assert error.value.code == 1