Package Exports
- @franciscokloganb/appwrite-database-migration-tool
- @franciscokloganb/appwrite-database-migration-tool/cli
- @franciscokloganb/appwrite-database-migration-tool/lib
Readme
Appwrite Database Migration Tool
Disclaimer: This NPM package is in a very early stage, please wait for v1.0.0 release to use on your own projects, unless you want to provide feedback or contribute.
Roadmap to v1.0.0
- [] Run codegen implementation from a consuming project;
- [] Run the setup implementation against live Appwrite databases from a consuming project;
- [] Run the run migration sequence implementation against live Appwrite databases from a consuming project;
- [] Create one down sequence flow
- [] Run the one down sequence flow against live Appwrite databases from consuming proeject;
- [] Add integration tests with mocked Appwrite responses using MSW;
Setting up
Create a
GitHub Repositoryto host your Appwrite functions.- You can use a repository you already own (e.g.,
myproject-functions).
- You can use a repository you already own (e.g.,
Create
environmentbranches.- For example, the
mainbranch can be assigned toproductionandstagingbranch can be assigned tostaging. This allows you to have multiple Appwrite projects, using a single functions repository containing with multiple serverless entrypoints. Allowing you to effectively test a function in the staging project, before deploying the changes to the main (production) project.
- For example, the
Set the repository as the Appwrite Serverless functions source.
Create a Appwrite Database per environment (project).
- Not needed if you already have a Database.
Create two Appwrite Functions, one called
Create Migrations Collectionand another calledRun Migration Sequence.Do this once per project.
Point the functions at different branches of the repository
- E.g.: point to main branch in production project, point to staging branch in the staging project.
Add the following contents to your functions respectively:
import { createMigrationCollection } from '@franciscokloganb/appwrite-database-migration-tool' export default async (ctx) => { await createMigrationCollection({ log: ctx.log, error: ctx.error, }) }
import { runMigrationSequence } from '@franciscokloganb/appwrite-database-migration-tool' export default async (ctx) => { await runMigrationSequence({ log: ctx.log, error: ctx.error, }) }
Each function will require access to the following environment variables.
- You can set them globally in your Appwrite project or scope them to each function.
- Warning: Ensure the values match across functions, if you opted for the scoped approach.
- Warning: Ensure the config does not change, if you ran the
runMigrationSequenceat least once. - Warning: Config can be changed anytime. We don't recommended it. Mistakes can cause synch issues.
# Required APPWRITE_API_KEY=<your-appwrite-api-key> # Required APPWRITE_ENDPOINT=<your-appwrite-endpoint> # Required MIGRATIONS_DATABASE_ID=<database-id> # Defaults to 'appwritedatabasemigrationtool' MIGRATIONS_COLLECTION_ID=<collection-id> # Defaults to 'Migrations' MIGRATIONS_COLLECTION_NAME=<collection-name> # Defaults to './migrations' MIGRATIONS_HOME=<relative-path-to-folder-where-runner-finds-your-migrations>Execute
Create Migrations Collectiononce and only once perproject/environment.- We prevent duplicate creations, but why take chances. 😇
- Double check that the
Migrationscollection was created with the following attributes:$id: Stringapplied: Booleanname: Stringtimestamp: Integer
Create your first migration (you should use this script everytime you want to create a new migration).
- This script is
Node.jscompatible. - Your description will be converted to
PascalCase.- Do not use whitespaces
- Do not use underscores
npx @franciscokloganb/appwrite-database-migration-tool/codegen/migration.js \ <relative-path-to-your-migration folder> \ <short-migration-description> ;
- This script is
Use the
databaseServiceparameter ofupanddown, which is an instance ofnode-appwriteDatabases class, to define your migration file contents.Once you are done, deploy your changes and execute the
Run Migration Sequencefunction.
Best Practises for Database Migration
There are recommendations that will help keep your team sane and safe.
- Always provide a meaningful descriptor for your migration.
- Attempt to follow the single-responsibility principle. Appwrite Cloud does not provide us with direct database access. That means we do not have real transaction mechanisms. Consequently, we recommend doing migrations in small steps. Remember, Appwrite Cloud Functions timeout after 15s, and you cannot perform a transaction over several collections and easily rollback all changes if something in that transaction fails.
- Always follow the expand-and-contract pattern, if required. Read here.
- Never change the file name of a migration file.
- Never change the class name of a migration class.
- Never change the contents of a migration that you have pushed to a production-like environment.
- Avoid abstractions in your migration files. They are subject to change in the future. If you use them, ensure that whatever happens, the output of the migration up sequence is always the same regardless. A change of output in a migration M may cause a migration M + x, x > 0, to no longer work as intended.
- Test your migration locally and your staging environment before releasing to production!
- Mistakes happen. If you pushed to production and applying 'down' is not possible, we recommend creating a new migration file to patch the issue. If that is not possible, restore your database to a previous point-in-time (backup) and apologize to your users.
See also: Prisma - Expand and Contract Pattern