Sequelize: instance.get is not a function (after upgrade)

时间:2019-04-08 12:45:54

标签: node.js typescript sequelize.js

On Sequelize version 3.x.x, the application runs perfectly with no issues. I tried to update this to version 4.x.x and fixed all the compile issues. However, there are some occasions where a sequelize error is thrown such as instance.getGroup is not a function. However, the IDE does allow me to pre-populate the methods on the instance, but upon auto complete it fills it to instance.getGroup

I have included some code below that I think is useful for the situation.

export interface IAccountInstance extends Sequelize.Instance<IAccountAttributes>, IAccountAttributes {
     /**
      * Gets all the Team objects associated with this instance.
      */
     getGroup: Sequelize.BelongsToManyGetAssociationsMixin<IGroupInstance>;
}

How the getGroups is invoked: When GraphQL requests an attribute of groups that exist on the account object, it will resolve with instance.getGroup() (this is where it breaks on v4, and numerous other methods that are done like this)

groups: {
            type: new GraphQL.GraphQLList(SchemaRegistrar.schemaMap.groups.graphqlSchema),
            resolve: (instance: IAccountInstance, args: any, context: any): any => {
                   if (!instance) {
                         return null;
                   }
                   return instance.getGroup();
            }
 },

From https://github.com/sequelize/sequelize/blob/v4/docs/upgrade-to-v4.md, I know there are breaking changes but i am having much luck.

How the schemas get initialized, on server startup, an action is called that created all the tables and sequelize models. There is more code but this is generally how it is done

const schemaModel: Sequelize.Model<any, any> = ServerGlobals.sequelize.define(
        schemaDef.tableName, schemaDef.sequelizeSchema, {
            instanceMethods: {
                schemaName: schemaDef.schemaName
            },
            freezeTableName: true
        });

Sequelize mentions this has changed (which is what needs to be updated in my code?...)

const Model = sequelize.define('Model', {
...
}, {
    classMethods: {
        associate: function (model) {...}
    },
    instanceMethods: {
        someMethod: function () { ...}
    }
});

to

const Model = sequelize.define('Model', {
...
});

// Class Method
Model.associate = function (models) {
    ...associate the models
};

// Instance Method
Model.prototype.someMethod = function () {..}

But Model.associate does not work for me and i'm not sure how I would make it work with my setup...

Any help is appreciated. I have gone through other people that have faced this issue but was not able to resolve it based off of their solutions.

UPDATE 1 The exact error from the stack trace is error: instance.getGroup is not a function TypeError: instance.getGroup is not a function

This is how the relationships are established. After the table schemas are initialized, the following is executed

_.forEach(
        this._sortedSchemas, (schema: AbstractSchemaDefinition<any, any>) =>
            schema.createSequelizeRelationships(SchemaRegistrar.schemaMap)
    );

createSequelizeRelationships is a function that returns nothing, but has the relationship properties to another table such as:

schemaMap.accounts.sequelizeModel.hasMany(
    schemaMap.groups.sequelizeModel,
    {
        as: groups,
        foreignKey: accountId
    }
);

1 个答案:

答案 0 :(得分:0)

这将是我拥有的新续集项目中一个简单对象的典型设置...并且花了我一段时间才能使关联正常工作

这将在一个名为loc_countries.js的文件中,并导入到第二个代码段的代码中

5.0

然后在我的index.js中,我通过您描述的forEach运行关联。

module.exports = function (sequelize, DataTypes) {
  const Country = sequelize.define('loc_countries', {
    id: {
      type: DataTypes.BIGINT,
      allowNull: false,
      primaryKey: true,
      autoIncrement: true,
    },
    name: {
      type: DataTypes.STRING,
      allowNull: true,
    },
    abbr2: {
      type: DataTypes.STRING,
      allowNull: true,
    },
    abbr3: {
      type: DataTypes.STRING,
      allowNull: true,
    },
  }, {
    freezeTableName: true,
    timestamps: false,
    tableName: 'loc_countries',
  });

  Country.associate = function (models) {
    models.Country.hasMany(models.ProvinceState, { as: 'ProvStates', foreignKey: 'loc_countries_id' });
  };

  return Country;
};