I wrote a CLI to migrate Appwrite databases

I wrote a CLI to migrate Appwrite databases

Over the course of the last week end I have been working on my appwrite-migration package.

In this blog post I want to show the functionality, what inspired me and how I am planning to continue this project.

Don't want to read?

Watch the video instead!

I have already recorded and published a demo video about this project. You can find it right here: https://www.youtube.com/watch?v=d1UhZmYRSHM&t=5s

Overview Functionality scope

Usage

    $ appwrite-migration [-v | --version] <command> [<args>]

Options
    --version, -v Show the CLI version
    --databaseId, -d The database id of your project. Currently not supported.
    --projectId, -p The id of your appwrite project
    --collection, -c The id of the collection that you want to operate on
    --endpoint The appwrite instance endpoint url. Defaults to "https://cloud.appwrite.com/v1"
    --file The file path for the operation
    --key The api key for your appwrite account

Commands

    login [-p | --projectId <projectId>] [--endpoint <AppwriteApiUrl>] [--key <apikey>] [--databaseId | -d <id>]
        Use this to enter your credentials. They will be stored in ${credentialsFile}

    new-migration [<migrationName>] [-d | --directory=./migrations]
        Create a new migration inside the directory.

    logout
        Clear the credentials file: ${credentialsFile}

    run [-d | --databaseId] [<migrationPath>]
        Runs the path that lies under this <migrationPath>. If the version specified in the migration is
        older than the metadata of the database. It won't be run.

    backup [-d | --databaseId] [-c | --collection <id>] [<downloadFolder>]
        Downloads all the data from all the collections (or specified within the -c flag)

    restore [-d | --databaseId][<collection> <file>]
        Restore the <collection> with the data from the provided <file>

    import [<schemaPath>]
        Creates the databases and collections from the generated schema.

    generate-schema [-d | --databaseId] [-f | --file <filepath>]
        Generates the schema and prints it out.
        If [--file] is provided stores the schema in the path.

Examples
    $ appwrite-migration --version
    $ appwrite-migration login --projectId 123893
    $ appwrite-migration run migrations/add_lastname_to_users.js -d primary
    $ appwrite-migration backup -c users -c countries ./download/ -d primary
    $ appwrite-migration restore -c users ./download/users.json -d primary

This, excluded of restore and backup, is the current functionality scope.

You can see there is the basic login command, the new-migration, run and run all commands.

Creating a migration script

new-migration is a simple generator that sets up a template for you. It is for convenience and the generated file acts as a guideline.

When creating a new migration script, the file is written to the ./migrations/ directory.

It is prefixed with the current date in seconds. This is to order them correctly. You may want to execute run-all later on. If we didn‘t keep track of the versions, we get a bad database state.

The migration script file itself has another date field. At least currently. When writing this post right now I am thinking of removing it for easier manageability. And falling back to the file name.

Anyways.. in this file you have access to a few symbols.

  1. defineMigration(migrationDate, cb) - a method that you need to call. It receives two parameters:

    1. migrationDate - acts as version and should be of type date

    2. A callback that receives just one parameter: the AppwriteMigrationClient

  1. this.databaseId - the db id it is run for

When building a migration you can call the api endpoints via the AppwriteMigrationClient.

await migrationClient
        .databases
        .createCollection(
            this.databaseId,
            'reports',
            'reports'
        );

The motivation behind it

I have been having this thought for quite a while now. It is/was a hard task to create a similar environment with Appwrite. With my approach I wanted a rails like database migration process.

  • git tracked

  • perfect for open source projects that don‘t share the same Appwrite account.

  • unified way

The projects future

I am planning to get this to a stable version. It is currently published in the name of my company. RoyalZSoftware. And I am also planning to keep it there.

I am thinking of refactoring the code a little, so that the app can be used better without relying on the cli.

Furthermore maybe I will message appwrite to give this thing a shout out, once stable.

Stay tuned and feel free to open a PR.

Did you enjoy this post?

Give it a thumbs up and share it with somebody that has been searching for a solution just like this.

Subscribe to the newsletter, to be the first who is receiving this posts.