db-migrate / node-db-migrate

Database migration framework for node
Other
2.32k stars 360 forks source link

Collection already exists error when applying script for mongo #737

Open JoeySelahJr opened 3 years ago

JoeySelahJr commented 3 years ago

I'm submitting a...

Current behavior

I'm trying to do db-migrate scripts for a mongo instance. I've created a really simple addIndex script as a test I run db-migrate up, it creates the migrations collection, it adds the index but no records are added to the migrations collection. db-migrate doesn't know it's ran the script. Second time I run db-migrate up, an error is thrown stating that the collection already exists.

Expected behavior

After running db-migrate up, the index is applied, the migrations collection is created with a document tracking what's been ran. The second time I run db-migrate up, nothing is applies since it's already been applied, and no errors occur.

Minimal reproduction of the problem with instructions

What is the motivation / use case for changing the behavior?

Can't use db-migration with mongo currently

Environment


db-migrate version: 0.11.12
db-migrate driver with versions: mongodb v4.4.6

Others:
This is the error message:
[ERROR] AssertionError [ERR_ASSERTION]: ifError got unwanted exception: Collection already exists. NS: forms.migrations
    at module.exports (/Users/jselah/src/forms-user-service/migrate/node_modules/db-migrate/lib/commands/helper/assert.js:9:14)
    at /Users/jselah/src/forms-user-service/migrate/node_modules/db-migrate/lib/commands/up.js:29:16
    at tryCatcher (/Users/jselah/src/forms-user-service/migrate/node_modules/bluebird/js/release/util.js:16:23)
    at Promise.errorAdapter [as _rejectionHandler0] (/Users/jselah/src/forms-user-service/migrate/node_modules/bluebird/js/release/nodeify.js:35:34)
    at Promise._settlePromise (/Users/jselah/src/forms-user-service/migrate/node_modules/bluebird/js/release/promise.js:601:21)
    at Promise._settlePromise0 (/Users/jselah/src/forms-user-service/migrate/node_modules/bluebird/js/release/promise.js:649:10)
    at Promise._settlePromises (/Users/jselah/src/forms-user-service/migrate/node_modules/bluebird/js/release/promise.js:725:18)
    at _drainQueueStep (/Users/jselah/src/forms-user-service/migrate/node_modules/bluebird/js/release/async.js:93:12)
    at _drainQueue (/Users/jselah/src/forms-user-service/migrate/node_modules/bluebird/js/release/async.js:86:9)
    at Async._drainQueues (/Users/jselah/src/forms-user-service/migrate/node_modules/bluebird/js/release/async.js:102:5)
    at Immediate.Async.drainQueues [as _onImmediate] (/Users/jselah/src/forms-user-service/migrate/node_modules/bluebird/js/release/async.js:15:14)
    at processImmediate (node:internal/timers:463:21)
    at Connection. (/Users/jselah/src/forms-user-service/migrate/node_modules/db-migrate-mongodb-nesto-fork/node_modules/mongodb/lib/core/connection/pool.js:451:61)
    at Connection.emit (node:events:379:20)
    at processMessage (/Users/jselah/src/forms-user-service/migrate/node_modules/db-migrate-mongodb-nesto-fork/node_modules/mongodb/lib/core/connection/connection.js:451:10)
    at TLSSocket. (/Users/jselah/src/forms-user-service/migrate/node_modules/db-migrate-mongodb-nesto-fork/node_modules/mongodb/lib/core/connection/connection.js:620:15)
    at TLSSocket.emit (node:events:379:20)
    at addChunk (node:internal/streams/readable:313:12)
    at readableAddChunk (node:internal/streams/readable:288:9)
    at TLSSocket.Readable.push (node:internal/streams/readable:227:10)
    at TLSWrap.onStreamRead (node:internal/stream_base_commons:190:23)
sktg84 commented 2 years ago

Any update on this? We are facing the same issue.

ilKhr commented 2 years ago

I do not know if this specifically solves your problem, but I will leave it here.

I use the try{} catch(err){} block and compare the error code in it

I use a different migration library, but I think the principle is clear to you

const collections = ['sessions', 'users'];

module.exports = {
  async up(db) {
    try {
      await Promise.all(collections.map((name) => db.createCollection(name)));
    } catch (err) {
      if (err.codeName !== 'NamespaceExists') {
        throw err;
      }
    }
  },

  async down(db) {
    await Promise.all(collections.map((name) => db.collection(name).drop()));
  },
};