sequelize: Index with name - s.replace is not a function

Bug Description

I have this in my Typsescript model for speciifying the indexes. I am using sequelize-auto to generate these, and it’s a valid format according to the sequelize docs:

FacebookPageConnections.init({
    facebookPlatformConnectionId: {
      type: DataTypes.INTEGER,
      allowNull: false,
      primaryKey: true,
      references: {
        model: 'facebook_platform_connections',
        key: 'id'
      },
      field: 'facebook_platform_connection_id'
    },
    pageId: {
      type: DataTypes.BIGINT,
      allowNull: false,
      primaryKey: true,
      field: 'page_id'
    },
    name: {
      type: DataTypes.STRING(255),
      allowNull: true
    },
    accessToken: {
      type: DataTypes.STRING(255),
      allowNull: true,
      field: 'access_token'
    },
    createdAt: {
      type: DataTypes.DATE,
      allowNull: false,
      field: 'created_at'
    },
    updatedAt: {
      type: DataTypes.DATE,
      allowNull: true,
      field: 'updated_at'
    },
    deletedAt: {
      type: DataTypes.DATE,
      allowNull: true,
      field: 'deleted_at'
    }
  }, {
    sequelize,
    tableName: 'facebook_page_connections',
    schema: 'public',
    timestamps: false,
    indexes: [
      {
        name: "facebook_page_connections_pkey",
        unique: true,
        fields: [
          { name: "facebook_platform_connection_id" },
          { name: "page_id" },
        ]
      },
    ]
  });

When calling bulkUpdate with UpdateOnDuplicate specified:

await FacebookPageConnections.bulkCreate(connectedAccounts, {
    updateOnDuplicate: ["name", "accessToken", "updatedAt", "deletedAt"],
  });

I receive the following error: s.replace is not a function

StackTrace:

'TypeError: s.replace is not a function\n    at Object.removeTicks (C:\\src\\test-project-node\\src\\api\\node_modules\\sequelize\\lib\\utils.js:351:12)\n    at Object.quoteIdentifier (C:\\src\\test-project-node\\src\\api\\node_modules\\sequelize\\lib\\dialects\\abstract\\query-generator\\helpers\\quote.js:50:35)\n    at PostgresQueryGenerator.quoteIdentifier (C:\\src\\test-project-node\\src\\api\\node_modules\\sequelize\\lib\\dialects\\abstract\\query-generator.js:900:24)\n    at C:\\src\\test-project-node\\src\\api\\node_modules\\se…\\sequelize\\lib\\dialects\\abstract\\query-generator.js:291:49)\n    at PostgresQueryInterface.bulkInsert (C:\\src\\test-project-node\\src\\api\\node_modules\\sequelize\\lib\\dialects\\abstract\\query-interface.js:834:27)\n    at recursiveBulkCreate (C:\\src\\test-project-node\\src\\api\\node_modules\\sequelize\\lib\\model.js:2711:52)\n    at processTicksAndRejections (node:internal/process/task_queues:96:5)\n    at async Function.bulkCreate (C:\\src\\test-project-node\\src\\api\\node_modules\\sequelize\\lib\\model.js:2837:12)'

It seems that the replaceTicks function is expecting a string array, when an object[] with name fields is acceptable. remove ticks function

What do you expect to happen?

Records to be Upserted as expected.

What is actually happening?

Error: s.replace is not a function

replaceTicks is expecting a string, when it is an object. s.replace needs to be s.name.replace in this scenario. Or the names need to be passed into this function.

Additional Info

I think this is either a fault of the replaceTicks function, or the code that generates the upsertKeys.

Environment

  • Sequelize version: 6.6.5
  • Node.js version: 16.9.1
  • If TypeScript related: TypeScript version: 4.4.3

Bug Report Checklist

How does this problem relate to dialects?

  • I think this problem happens regardless of the dialect.

Would you be willing to resolve this issue by submitting a Pull Request?

  • No, I don’t have the time and I wouldn’t even know how to start.

About this issue

  • Original URL
  • State: open
  • Created 3 years ago
  • Reactions: 7
  • Comments: 33 (11 by maintainers)

Most upvoted comments

Thank you ❤️ I’ll look into fixing this as soon as I’m available

I have a functioning workaround requiring no fixes in Sequelize itself, but some checks or type defs might help future-proof the functionality:

IF you are defining the indexes declaratively like in the original example from @MrNickGreene don’t define your field list using the object notation with names, IE

        fields: [
          "facebook_platform_connection_id",
          "page_id",
        ]

Instead of:

        fields: [
          { name: "facebook_platform_connection_id" },
          { name: "page_id" },
        ]

If you’re defining your models using sequelize-typescript’s @Table and @Column decorators, define the indexes on the @Table decorator so that you can specify the database field names:

@Table({
  modelName: 'facebook_platform_connections',
  freezeTableName: true,
  indexes: [{ name: 'facebook_page_connections_pkey', fields: ['facebook_platform_connection_id', 'page_id'], unique: true }],
})

up

Same issue here

No ETA, my focus is currently on #13817. If you know what is causing the issue, don’t hesitate to open a PR with a test and the fix, otherwise this will have to wait until that other issue is resolved 😕

Same issue

Hi everyone! Same bug here. @ephys do you have an ETA for the fix? Thanks!

@ephys ok, will provide it soon

same issue, using typescript. seems like object gets passed to removetick but only during bulkcreate.

object looks like { name: ‘id’, length: undefined, order: undefined, collate: undefined }

gl

I have the same issue