Sequelize: instance.get не является функцией (после обновления)

#node.js #typescript #sequelize.js

#node.js #typescript #sequelize.js

Вопрос:

В Sequelize версии 3.x.x приложение работает отлично, без каких-либо проблем. Я попытался обновить это до версии 4.x.x и исправил все проблемы с компиляцией. Однако в некоторых случаях возникает ошибка sequelize, например instance.getGroup is not a function . Тем не менее, IDE позволяет мне предварительно заполнять методы в экземпляре, но при автозаполнении он заполняет его instance.getGroup

Я включил ниже некоторый код, который, на мой взгляд, полезен для данной ситуации.

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

Как вызывается GetGroups: когда GraphQL запрашивает атрибут groups , который существует в account объекте, он будет разрешен с instance.getGroup() помощью (здесь он прерывается в версии 4 и многих других методах, которые выполняются подобным образом)

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

Из https://github.com/sequelize/sequelize/blob/v4/docs/upgrade-to-v4.md , Я знаю, что есть серьезные изменения, но мне очень повезло.

Как схемы инициализируются, при запуске сервера вызывается действие, которое создает все таблицы и модели sequelize. Кода больше, но обычно это делается так

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

Sequelize упоминает, что это изменилось (что нужно обновить в моем коде? …)

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

Для

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

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

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

Но Model.associate у меня не работает, и я не уверен, как я заставлю его работать с моей настройкой…

Любая помощь приветствуется. Я прошел через других людей, которые столкнулись с этой проблемой, но не смогли решить ее на основе своих решений.

ОБНОВЛЕНИЕ 1 Точная ошибка трассировки стека error: instance.getGroup is not a function TypeError: instance.getGroup is not a function

Вот как устанавливаются отношения. После инициализации схем таблиц выполняется следующее

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

createSequelizeRelationships это функция, которая ничего не возвращает, но имеет свойства связи с другой таблицей, такие как:

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

Ответ №1:

Так что это была бы типичная настройка для простого объекта в новом проекте sequelize, который у меня есть … и мне потребовалось некоторое время, чтобы заставить ассоциации работать

Это будет в файле с именем loc_countries.js , и он импортируется в код во втором фрагменте

 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;
};
  

Затем в моем index.js это то место, где я провел ассоциации через forEach, который вы описали..

 const models = {
  Country: sequelize.import('./loc_countries'),
  ProvinceState: sequelize.import('./loc_state_prov'),
  City: sequelize.import('./loc_inc_places'),  
};

Object.keys(models).forEach((modelName) => {
  if ('associate' in models[modelName]) {
    // console.log(models[modelName]);
    models[modelName].associate(models);
  }
});
  

Комментарии:

1. Спасибо за ответ, Грег. Я посмотрю, смогу ли я изменить то, что у меня есть, на то, что вы создали… с моей стороны это немного сложно, поскольку это устоявшаяся система (содержит МНОГО файлов схемы, которые мне пришлось бы изменить, чтобы иметь ваш формат). То, что мы имеем, очень похоже на vivacitylabs.com/setup-typescript-sequelize на самом деле. Я буду держать вас в курсе того, что происходит