sequelize: Bug when using ENUM datatype with Postgres

What you are doing?

export const Category = {
  define: (db: Sequelize.Sequelize): Sequelize.Model<ICategoryInstance, ICategoryAttributes> => (
    db.define<ICategoryInstance, ICategoryAttributes>('category', {
      id: {
        type: Sequelize.INTEGER,
        primaryKey: true,
        allowNull: false,
        unique: true,
        autoIncrement: false
      },
      title: {
        type: Sequelize.STRING
      },
      type: {
        type: Sequelize.ENUM,
        values: ['bundle', 'goals_bundle', 'shorts_bundle', 'singles_bundle', 'goal'],
      }
    }, {
      underscored: true
    })
  )
};

What do you expect to happen?

I expect to have an ENUM datatype attribute on the category table.

What is actually happening?

The database won’t sync, I get an error connecting to the database.

Output, either JSON or SQL Logging around the code, I was eventually able to find this error:

[1] [nodemon] restarting due to changes...
[1] [nodemon] starting `node build/src/index.js build/index.js`
[1] Running enviroment production
[1] Executing (default): SELECT 1+1 AS result
[1] Connected to database at localhost://inscape-dev2
[1] associating model User
[1] associating model Journal
[1] associating model Event
[1] associating model Audio
[1] associating model Sequence
[1] associating model Meditation
[1] associating model Category
[1] associating model Favorite
[1] Executing (default): DROP TABLE IF EXISTS "favorites" CASCADE;
[1] Executing (default): DROP TABLE IF EXISTS "audios" CASCADE;
[1] Executing (default): DROP TABLE IF EXISTS "events" CASCADE;
[1] Executing (default): DROP TABLE IF EXISTS "sequences" CASCADE;
[1] Executing (default): DROP TABLE IF EXISTS "meditations" CASCADE;
[1] Executing (default): DROP TABLE IF EXISTS "journals" CASCADE;
[1] Executing (default): DROP TABLE IF EXISTS "users" CASCADE;
[1] Executing (default): DROP TABLE IF EXISTS "categories" CASCADE;
[1] Executing (default): DROP TYPE IF EXISTS "public"."enum_categories_type";
[1] Executing (default): DROP TABLE IF EXISTS "categories" CASCADE;
[1] Executing (default): DROP TYPE IF EXISTS "public"."enum_categories_type";
[1] Executing (default): SELECT t.typname enum_name, array_agg(e.enumlabel ORDER BY enumsortorder) enum_value FROM pg_type t JOIN pg_enum e ON t.oid = e.enumtypid JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace WHERE n.nspname = 'public' AND t.typname='enum_categories_type' GROUP BY 1
[1] Executing (default): DROP TYPE IF EXISTS "public"."enum_categories_type"; CREATE TYPE "public"."enum_categories_type" AS ENUM('bundle', 'goals_bundle', 'shorts_bundle', 'singles_bundle', 'goal');
[1] TypeError: Cannot read property '0' of undefined
[1]     at query.catch.then.then.queryResult (/Users/jacob/Documents/AD60/Repositories/inscape-middleware/node_modules/sequelize/lib/dialects/postgres/query.js:112:17)
[1]     at tryCatcher (/Users/jacob/Documents/AD60/Repositories/inscape-middleware/node_modules/sequelize/node_modules/bluebird/js/release/util.js:16:23)
[1]     at Promise._settlePromiseFromHandler (/Users/jacob/Documents/AD60/Repositories/inscape-middleware/node_modules/sequelize/node_modules/bluebird/js/release/promise.js:512:31)
[1]     at Promise._settlePromise (/Users/jacob/Documents/AD60/Repositories/inscape-middleware/node_modules/sequelize/node_modules/bluebird/js/release/promise.js:569:18)
[1]     at Promise._settlePromise0 (/Users/jacob/Documents/AD60/Repositories/inscape-middleware/node_modules/sequelize/node_modules/bluebird/js/release/promise.js:614:10)
[1]     at Promise._settlePromises (/Users/jacob/Documents/AD60/Repositories/inscape-middleware/node_modules/sequelize/node_modules/bluebird/js/release/promise.js:693:18)
[1]     at Async._drainQueue (/Users/jacob/Documents/AD60/Repositories/inscape-middleware/node_modules/sequelize/node_modules/bluebird/js/release/async.js:133:16)
[1]     at Async._drainQueues (/Users/jacob/Documents/AD60/Repositories/inscape-middleware/node_modules/sequelize/node_modules/bluebird/js/release/async.js:143:10)
[1]     at Immediate.Async.drainQueues (/Users/jacob/Documents/AD60/Repositories/inscape-middleware/node_modules/sequelize/node_modules/bluebird/js/release/async.js:17:14)
[1]     at runCallback (timers.js:666:20)
[1]     at tryOnImmediate (timers.js:639:5)
[1]     at processImmediate [as _immediateCallback] (timers.js:611:5)
[1] Error connecting to localhost://inscape-dev2
[1] Register Plugin Good Logger v1.0.0
[1] Register Plugin Swagger Documentation v1.0.0
[1] Register Plugin JWT Authentication v1.0.0
[1] Register Plugin Oauth (Facebook) v1.0.0
[1] Register Plugin Hapi API Versioning v1.0.0
[1] Error starting server: TypeError: Cannot read property 'Category' of undefined

I noticed in an if statement @ sequelize/lib/dialects/postgres/query.js:112:17, there is this if statement: if (rows[0] && rows[0].sequelize_caught_exception !== undefined) { if this is written as follows: if (rows && rows[0] && rows[0].sequelize_caught_exception !== undefined) {

I know longer face the bug and I am able to sync my database with the ENUM properly. This fix is super easy! I made a local sequelize branch and ran the tests. Everything seemed to work fine, but I couldn’t manage to push up to make a PR (though I tried following the directions supplied).

Dialect: postgres Database version: 7.0.0 Sequelize version: 4.4.2

This is a really quick fix, so please get to it soon if possible. Thanks for all of the hard work!

~Jacob

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 15
  • Comments: 17 (3 by maintainers)

Most upvoted comments

still an issue

I guess the updated pg module (v7.x) caused this problem. Please try pg module v6.4.2.

It seems that the issue happens when there’s an attribute that has the same name as the column. For example, it happens in this case:

budget: {
  field: 'budget',
  type: Sequelize.ENUM('LOW', 'HIGH'),
  notNull: true,
},

But not in this case:

noiseLevel: {
  field: 'noise_level',
  type: Sequelize.ENUM('QUIET', 'SOME_CHATTER', 'LOUD'),
  notNull: true,
},

See the differences between the attribute names and the column names (field).

Still an issue.

Still encountering this issue when using pg@7 or above. Only solution for the time being is to downgrade pg. I do wish I could use pg@7 with sequelize, though