diff --git a/README.md b/README.md index 6cff0efb..221a8529 100644 --- a/README.md +++ b/README.md @@ -329,30 +329,64 @@ a microservice that provides user authentication against an LDAP server and retu ### Migrations -Migration scripts are located inside the `inventory_management_system/migrations/scripts`. See the -`example_migration.py` for an example on how to implement one. Any new migrations added should be automatically picked -up and shown via +#### Adding a migration + +To add a migration first use + +```bash +ims-migrate create +``` + +to create a new one inside the `inventory_management_system/migrations/scripts` directory. Then add the code necessary +to perform the migration. See `_example_migration.py` for an example on how to implement one. + +#### Performing forward migrations + +Before performing a you can first check the current status of the database and any outstanding migrations using ```bash -ims-migrate list +ims-migrate status ``` -or +or in Docker ```bash docker exec -it inventory_management_system_api_container ims-migrate list ``` -if running in Docker. +Then to perform all outstanding migrations up to the latest one use + +```bash +ims-migrate forward latest +``` -To perform a migration you should use +You may also specify a specific migration name to apply instead which will apply all migrations between the current +applied one and the specified one. A prompt will be shown to ensure the migrations being applied are sensible. + +#### Performing backward migrations + +To revert the database by performing backwards migrations you can first use ```bash -ims-migrate forward +ims-migrate status ``` -To revert the same migration use +to check the current status of the database and available migrations and then use ```bash ims-migrate backward ``` + +to perform all backward migrations to get from the current database state back to the state prior to the chosen +migration name (i.e. it also performs the backward migration for the given migration name). + +#### Forcing migration state + +If for some reason the migration state is different to what you expect it may be forced via + +```bash +ims-migrate set +``` + +This is already set to `latest` automatically when using the `dev_cli` to regenerate mock data so that the dump retains +the expected state. diff --git a/data/mock_data.dump b/data/mock_data.dump index a3cacd1c..8734ca82 100644 Binary files a/data/mock_data.dump and b/data/mock_data.dump differ diff --git a/inventory_management_system_api/migrations/script.py b/inventory_management_system_api/migrations/script.py index 20c8f8f2..bced569d 100644 --- a/inventory_management_system_api/migrations/script.py +++ b/inventory_management_system_api/migrations/script.py @@ -5,6 +5,7 @@ import logging import sys from abc import ABC, abstractmethod +from typing import Optional from inventory_management_system_api.core.database import get_database from inventory_management_system_api.migrations.core import ( @@ -23,17 +24,30 @@ database = get_database() -def check_user_sure() -> bool: +def check_user_sure(message: Optional[str] = None, skip: bool = False) -> bool: """ Asks user if they are sure action should proceed and exits if not. + :param message: Message to accompany the check. + :param skip: Whether to skip printing out the message and performing the check. :return: Whether user is sure. """ + if skip: + return True + + print(message) + print() answer = input("Are you sure you wish to proceed? ") return answer in ("y", "yes") +def add_skip_args(parser: argparse.ArgumentParser): + """Adds common arguments for skipping user prompts.""" + + parser.add_argument("--yes", "-y", help="Specify to skip all are you sure prompts", action="store_true") + + class SubCommand(ABC): """Base class for a sub command.""" @@ -198,6 +212,8 @@ def __init__(self): def setup(self, parser: argparse.ArgumentParser): parser.add_argument("name", help="Name of the last migration the database currently matches.") + add_skip_args(parser) + def run(self, args: argparse.Namespace): available_migrations = find_available_migrations() @@ -206,10 +222,10 @@ def run(self, args: argparse.Namespace): except ValueError: sys.exit(f"Migration '{args.name}' was not found in the available list of migrations") - print(f"This operation will forcibly set the latest migration to '{available_migrations[end_index]}'") - print() - - if check_user_sure(): + if check_user_sure( + message=f"This operation will forcibly set the latest migration to '{available_migrations[end_index]}'", + skip=args.yes, + ): set_previous_migration(available_migrations[end_index]) diff --git a/scripts/dev_cli.py b/scripts/dev_cli.py index 5d803fe9..11d95021 100644 --- a/scripts/dev_cli.py +++ b/scripts/dev_cli.py @@ -234,6 +234,10 @@ def run(self, args: argparse.Namespace): generate_mock_data() except ImportError: logging.error("Failed to find generate_mock_data.py") + + logging.info("Ensuring previous migration is set to latest...") + run_command(["ims-migrate", "set", "latest", "-y"]) + if args.dump: logging.info("Dumping output...") # Dump output again