Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

typeorm:migration create on New Project Does Not Recognize Entities - "No changes in database schema were found - cannot generate a migration."

I'm having trouble creating the initial migration for a nestjs-typeorm-mongo project.
I have cloned this sample project from nestjs that uses typeorm with mongodb. The project does work in that when I run it locally after putting a "Photo" document into my local mongo with db named "test" and collection "photos" then I can call to localhost:3000/photo and receive the photo documents.

Now I'm trying to create migrations with the typeorm cli using this command:

./node_modules/.bin/ts-node ./node_modules/typeorm/cli.js migration:generate -n initial

...but it's not working. I am not able to create an initial commit- even after setting "synchronize: false" in my app.module.ts file I always get the error:

No changes in database schema were found - cannot generate a migration. To create a new empty migration use "typeorm migration:create" command when trying to generate a migration... 🤔

Other than changing synchronize to false, the only other change I made was adding an ormconfig.json file in the project root by running typeorm init --database mongodb:

{
   "type": "mongodb",
   "database": "test",
   "synchronize": true,
   "logging": false,
   "entities": [
      "src/**/*.entity.ts"
   ],
   "migrations": [
      "src/migration/**/*.ts"
   ],
   "subscribers": [
      "src/subscriber/**/*.ts"
   ],
   "cli": {
      "entitiesDir": "src",
      "migrationsDir": "src/migration",
      "subscribersDir": "src/subscriber"
   }
}
like image 747
Jim Avatar asked Sep 05 '20 22:09

Jim


People also ask

How do I create a migration file in TypeORM?

You need to create a new migration with the following SQL query (postgres dialect): ALTER TABLE "post" ALTER COLUMN "title" RENAME TO "name"; Once you run this SQL query your database schema is ready to work with your new codebase. TypeORM provides a place where you can write such sql queries and run them when needed.

What is synchronize in TypeORM?

This option automatically syncs your database tables with the given entities each time you run this code. This option is perfect during development, but in production you may not want this option to be enabled. Use command line tools and run schema sync manually in the command line: typeorm schema:sync.


1 Answers

Once you are using MongoDB, you don't have tables and have no need to create your collections ahead of time. Essentially, MongoDB schemas are created on the fly!

Under the hood, if the driver is MongoDB, the command typeorm migration:create is bypassed so it is useless in this case. You can check yourself the PR #3304 and Issue #2867.

However, there is an alternative called migrate-mongo which provides a way to archive incremental, reversible, and version-controlled way to apply schema and data changes. It’s well documented and actively developed.

migrate-mongo example

Run npm install -g migrate-mongo to install it.

Run migrate-mongo init to init the migrations tool. This will create a migrate-mongo-config.js configuration file and a migrations folder at the root of our project:

|_ src/
|_ migrations/
   |- 20200606204524-migration-1.js
   |- 20200608124524-migration-2.js
   |- 20200808114324-migration-3.js
|- migrate-mongo.js
|- package.json
|- package-lock.json

Your migrate-mongo-config.js configuration file may look like:

// In this file you can configure migrate-mongo
const env = require('./server/config')
const config = {
  mongodb: {
    // TODO Change (or review) the url to your MongoDB:
    url: env.mongo.url || "mongodb://localhost:27017",

    // TODO Change this to your database name:
    databaseName: env.mongo.dbname || "YOURDATABASENAME",

    options: {
      useNewUrlParser: true, // removes a deprecation warning when connecting
      useUnifiedTopology: true, // removes a deprecating warning when connecting
      //   connectTimeoutMS: 3600000, // increase connection timeout up to 1 hour
      //   socketTimeoutMS: 3600000, // increase socket timeout up to 1 hour
    }
  },

  // The migrations dir can be a relative or absolute path. Only edit this when really necessary.
  migrationsDir: "migrations",

  // The MongoDB collection where the applied changes are stored. Only edit this when really necessary.
  changelogCollectionName: "changelog"
};
module.exports = config;

Run migrate-mongo create name-of-my-script to add a new migration script. A new file will be created with a corresponding timestamp.

/*
|_ migrations/
   |- 20210108114324-name-of-my-script.js
*/

module.exports = {
    function up(db) {
        return db.collection('products').updateMany({}, { $set: { quantity: 10 } })
    }
    
    function down(db) {
        return db.collection('products').updateMany({}, { $unset: { quantity: null } })
    }
}

The database changelog: In order to know the current database version and which migration should apply next, there is a special collection that stores the database changelog with information such as migrations applied, and when where they applied.

enter image description here

To run your migrations, simply run the command: migrate-mongo up

You can find a full example in this article MongoDB Schema Migrations in Node.js

like image 64
Willian Avatar answered Dec 08 '22 01:12

Willian