ilovepixelart / ts-migrate-mongoose

A node/typescript based migration framework for mongoose
MIT License
72 stars 6 forks source link

Auto create and run new migrations, when doing "migrate up" #323

Closed hannesroth88 closed 3 months ago

hannesroth88 commented 3 months ago

Is your feature request related to a problem? Please describe. When I do "npx migrate up -s", i would like the new migration scripts to be run. Instead i get:

Synchronizing database with file system migrations...
There are no pending migrations
Current migrations status: 
Synchronizing database with file system migrations...
There are no migrations to list

I am using NestJs and used the example NestJs Repo.

Describe the solution you'd like I don't want to explicitly use "npx migrate create xyz" before. So I could easily integrate it in the startup script as I am running multiple environments. Is this already possible? Assuming we use a naming syntax like isodate-timestamp-xyz.ts

Describe alternatives you've considered using create command within NestJs or Ci/CD, but would I need to write logic to detect whether its a new migration from DB? Feels like this logic should reside in this package.

Additional context not sure if it relates to #312

ilovepixelart commented 3 months ago

Hello @hannesroth88 did you consider using programmatic mode https://github.com/ilovepixelart/ts-migrate-mongoose/tree/main/examples/programmatic-usage This should cover your case and you can run it on sturtup

hannesroth88 commented 3 months ago

Thanks for the fast reply.

Turned out I wrongly set it up. Guess it was the auto-sync setting, which wasn't set to true Now the Cli is doing exactly how I wanted the migration to be. This was my missing piece synchronizing-your-db-with-new-migrations If migration is not yet on the Database of the users / environment, migrate up imports it from file system

The programmatic way in NestJs is also working fine, I implemented it like this

NestJs main.ts

import Migrator from 'ts-migrate-mongoose';
import configMigration from 'migrate';

export class MigrationClient {
  static async run() {
    if (process.env.NODE_ENV != 'production') {
      const migrator = await Migrator.connect(configMigration);
      const sanitizedConnectionString = sanitizeMongoConnectionString(configMigration.uri);
      configMigration.uri = sanitizedConnectionString;
      console.info('Running migrations with: ', configMigration);

      // Migrate Up
      await migrator.run('up');

      await migrator.close();
    } else {
      console.info('Skipping migrations in production, run manually');
    }
  }
}

function sanitizeMongoConnectionString(connectionString: string): string {
  return connectionString.replace(/:\/\/[^:]+:[^@]+@/, '://<user>:<password>@');
}

./migrate.ts

import IMigratorOptions from 'ts-migrate-mongoose/dist/cjs/types/interfaces/IMigratorOptions';

const config: IMigratorOptions = {
  uri: process.env.MIGRATE_MONGO_URI,
  collection: process.env.MIGRATE_MONGO_COLLECTION,
  // configPath: process.env.MIGRATE_CONFIG_PATH,
  migrationsPath: process.env.MIGRATE_MIGRATIONS_PATH,
  // templatePath: process.env.MIGRATE_TEMPLATE_PATH,
  autosync: Boolean(process.env.MIGRATE_AUTOSYNC)
};

export default config;

Thanks for this amazing project 👏