onetable-cli

    1.2.1 • Public • Published

    OneTable

    One Table to Rule Them All

    OneTable Migrate CLI

    npm npm

    The DynamoDB OneTable Migration CLI is a command line tool for orchestrating DynamoDB migrations when using DynamoDB OneTable and OneTable Migrate.

    The CLI is ideal for development teams to initialize and reset database contents and for production use to control and sequence step-wise database upgrades.

    The OneTable CLI was used in production by the SenseDeep Serverless Troubleshooter for all DynamoDB access for a year before it was published as an NPM module.

    OneTable Migrate CLI Features

    • Simple command line utility to control and manage DynamoDB schema and contents.
    • Mutate database schema and contents via discrete, reversible migrations.
    • Migrate upwards, downwards, to specific versions.
    • Automated, ordered sequencing of migrations in both directions.
    • Operate on local databases, remote databases via AWS credentials and via Lambda proxy.
    • Add and remove seed data in any migration.
    • Quick reset of DynamoDB databases for development.
    • Generate migration scripts.
    • Show database status and list applied migrations.
    • Show outstanding migrations.
    • Stored history of migrations.
    • Minimal dependencies.

    Installation

    NOTE: this package requires NPM version 7.0 or later. The version 6.x of NPM that comes with Node v14 will not work as it does not support local packages.

    npm i onetable-cli -g

    Getting Started

    To get started, create a directory for your migrations in your project.

    mkdir ./migrations

    Then create a migrate.json with your DynamoDB OneTable configuration. We use JSON5 so you can use Javascript object literal syntax.

    {
        onetable: {
            name: 'your-dynamo-table',
            //  Other onetable configuration parameters.
        }
    }

    Set the name property to the name of your DynamoDB table.

    If you need to have your migrations in a different directory, you can set the migrate.json dir property to point to the directory containing the migrations themselves.

    You pass your OneTable configuration via the onetable collection. Ensure your crypto, delimiter, nulls and typeField settings match your deployed code. If you have these set to non-default settings in your code, add them to your migrate.json onetable map to match.

    Generate a stub migration

    Migrations are Javascript files that export the methods up and down to apply the migration and a description property. The migration must nominate a version and provide the OneTable schema that applies for the table data at this version level.

    cd ./migrations
    onetable generate migration

    This will create a 0.0.1.js migration that contains the following. Edit the up and down methods and description to suit.

    The db property is the OneTable Table instance. This migrate property is an instance of the CLI Migrate class.

    export default {
        version: '0.0.1',
        description: 'Purpose of this migration',
        schema: Schema,
        async up(db, migrate) {
            // await db.create('Model', {})
        },
        async down(db, migrate) {
            // await db.remove('Model', {})
        }
    }

    Examples

    Apply the next migration

    onetable up

    Reverse the last migration

    onetable down

    Repeat the last migration

    onetable repeat

    Migrate to a specific version (up or down)

    onetable 0.1.3

    Apply all outstanding migrations

    onetable all

    Show the last applied migration

    onetable status

    Show applied migrations

    onetable list

    Show outstanding migrations not yet applied

    onetable outstanding

    Reset the database to the latest migration. This should reset the database and apply the latest.js migration. The purpose of the latest migration is to have one migration that can quickly create a new database with the latest schema without having to apply all historical migrations.

    onetable reset

    Generate a specific version migration

    onetable --bump 2.4.3 generate

    Do a dry run for a migration and not execute

    onetable --dry up

    Command Line Options

    --aws-access-key                    # AWS access key
    --aws-region                        # AWS service region
    --aws-secret-key                    # AWS secret key
    --bump [major,minor,patch]          # Version digit to bump in generation
    --config ./migrate.json             # Migration configuration
    --crypto cipher:password            # Crypto to use for encrypted attributes
    --dir directory                     # Change to directory to execute
    --dry                               # Dry-run, don't execute
    --endpoint http://host:port         # Database endpoint
    --force                             # Force action without confirmation
    --profile prod|qa|dev|...           # Select configuration profile
    --quiet                             # Run as quietly as possible
    --version                           # Emit version number
    

    Accessing AWS

    You can configure access to your DynamoDB table in your AWS account several ways:

    • via command line options
    • via the migrate.json
    • via environment variables
    • via proxy

    Via command line option:

    onetable --aws-access-key key --aws-secret-key secret --aws-region us-east-1
    

    Via migrate.json

    {
        aws: {
            accessKeyId: 'your-key',
            secretAccessKey: 'your-access',
            region: 'us-east-1'
        }
    }
    

    Or via environment variables:

    export AWS_ACCESS_KEY_ID=your-access-key
    export AWS_SECRET_ACCESS_KEY=your-secret-key
    export AWS_DEFAULT_REGION=us-east-1
    

    You can also use:

    export AWS_PROFILE=aws-profile-name
    export AWS_REGION=us-east-1
    

    To access a local DynamoDB database, set the migrate.json aws.endpoint property to point to the listening endpoint.

    {
        aws: {
            endpoint: 'http://localhost:8000'
        }
    }
    

    To communicate with a Lambda hosting the OneTable Migrate Library, set the arn field to the ARN of your Lambda function. Then define your AWS credentials as described above to grant access for the CLI to your Lambda.

    {
        arn: 'arn:aws:lambda:us-east-1:123456789012:function:migrate-prod-invoke'
    }
    

    Remote Connections

    The OneTable CLI uses the OneTable Migrate controller library internally to manage migrations. As such, DynamoDB I/O is performed from within the OneTable Migrate lambda. This means I/O travels to and from CLI command to the region hosting the OneTable Migrate lambda.

    If you have large databases or complex migrations, you should host the OneTable Migrate library in the same AWS region and availablity zone as your DynamoDB instance. This will accelerate migrations by minimizing the I/O transfer time. With this split deployment of CLI and Migration library, higher volume migrations execute more quickly.

    To configure remote control of migrations, set the migrate.json arn property to the ARN of your migration Lambda that hosts the Migration Library. See OneTable Migrate for more details about Lambda hosting of the OneTable Migrate library.

    Latest Migration

    You can create a special latest migration that is used for the migrate reset command which is is a quick way to get a development database up to the current version.

    The latest migration should remove all data from the database and then initialize the database equivalent to applying all migrations.

    When creating your latest.js migration, be very careful when removing all items from the database. We typically protect this with a test against the deployment profile to ensure you never do this on a production database.

    Sample latest.js migration:

    export default {
        version: '0.0.1',
        description: 'Database reset to latest version',
        schema: Schema,
        async up(db, migrate) {
            if (migrate.params.profile == 'dev') {
                await removeAllItems(db)
            }
            //  Provision required database data
        },
        async down(db, migrate) {
            if (migrate.params.profile == 'dev') {
                await removeAllItems(db)
            }
        },
    }
    async function removeAllItems(db) {
        do {
            items = await db.scanItems({}, {limit: 100})
            for (let item of items) {
                await db.deleteItem(item)
            }
        } while (items.length)
    }

    Profiles

    You can use profiles in your migrate.json to have specific configuration for different build profiles.

    Profiles are implemented by copying the properties from the relevant profile.NAME collection to the top level. For example:

    Here is a sample migrate.json with profiles:

    {
        profiles: {
            dev: {
                dir: './migrations',
                name: 'sensedb',
                endpoint: 'http://localhost:8000'
            },
            qa: {
                name: 'sensedb',
                arn: 'arn:aws:lambda:us-east-1:xxxx:function:migrate-qa-invoke'
            },
            prod: {
                name: 'sensedb',
                arn: 'arn:aws:lambda:us-east-1:xxxx:function:migrate-prod-invoke'
            }
        }
    }

    If the profile is set to 'dev', the dev profile properties of dir, name, and endpoint are copied to the root level.

    References

    Participate

    All feedback, contributions and bug reports are very welcome.

    Contact

    You can contact me (Michael O'Brien) on Twitter at: @SenseDeepCloud, or email and ready my Blog.

    SenseDeep

    Please try our Serverless trouble shooter SenseDeep.

    Install

    npm i onetable-cli

    DownloadsWeekly Downloads

    26

    Version

    1.2.1

    License

    MIT

    Unpacked Size

    78 kB

    Total Files

    29

    Last publish

    Collaborators

    • sensedeep