Overview

In LoopBack, auto-migration helps the user create relational database schemasbased on definitions of their models. Auto-migration can facilitate thesynchronization of the backing database and models so that they match, such asin cases where the database needs to be changed in order to match the models.LoopBack offers two ways to do this:

  • Auto-migrate: Drop schema objects if they already exist and re-create thembased on model definitions. Existing data will be lost.

  • Auto-update: Change database schema objects if there is a differencebetween the objects and model definitions. Existing data will be kept.

Warning: Auto-update will attempt to preserve data whileupdating the schema in your target database, but this is not guaranteed to besafe.

Please check the documentation for your specific connector(s) for a detailedbreakdown of behaviors for automigrate!

Examples

LoopBack applications are typically using RepositoryMixin to enhance the coreApplication class with additional repository-related APIs. One of such methodsis migrateSchema, which iterates over all registered datasources and asks themto migrate schema of models they are backing. Datasources that do not supportschema migrations are silently skipped.

In the future, we would like to provide finer-grained control of database schemaupdates, learn more in the GitHub issue#487 Database Migration Management Framework

Auto-update database at start

To automatically update the database schema whenever the application is started,modify your main script to execute app.migrateSchema() after the applicationwas bootstrapped (all repositories were registered) but before it is actuallystarted.

src/index.ts

  1. export async function main(options: ApplicationConfig = {}) {
  2. const app = new TodoListApplication(options);
  3. await app.boot();
  4. await app.migrateSchema();
  5. await app.start();
  6. const url = app.restServer.url;
  7. console.log(`Server is running at ${url}`);
  8. return app;
  9. }

Auto-update the database explicitly

It’s usually better to have more control about the database migration andtrigger the updates explicitly. To do so, projects scaffolded using lb4 appcome with a custom CLI script src/migrate.ts to run schema migration. Checkout e.g.Todo example appto see the full source code of the script.

Besides the migration CLI, new projects come with a handy npm script to run themigration too.

The migration process consists of two steps now:

  • Build the project:
  1. $ npm run build
  • Migrate database schemas (alter existing tables):
  1. $ npm run migrate

Alternatively, you can also tell the migration script to drop any existingschemas:

  1. $ npm run migrate -- --rebuild

Implement additional migration steps

In some scenarios, the application may need to define additional schemaconstraints or seed the database with predefined model instances. This can beachieved by overriding the migrateSchema method provided by the mixin.

The example below shows how to do so in our Todo example application.

src/application.ts

  1. import {TodoRepository} from './repositories';
  2. // skipped: other imports
  3. export class TodoListApplication extends BootMixin(
  4. ServiceMixin(RepositoryMixin(RestApplication)),
  5. ) {
  6. // skipped: the constructor, etc.
  7. async migrateSchema(options?: SchemaMigrationOptions) {
  8. // 1. Run migration scripts provided by connectors
  9. await super.migrateSchema(options);
  10. // 2. Make further changes. When creating predefined model instances,
  11. // handle the case when these instances already exist.
  12. const todoRepo = await this.getRepository(TodoRepository);
  13. const found = await todoRepo.findOne({where: {title: 'welcome'}});
  14. if (found) {
  15. todoRepo.updateById(found.id, {isComplete: false});
  16. } else {
  17. await todoRepo.create({title: 'welcome', isComplete: false});
  18. }
  19. }
  20. }