首页 文章

Sequelize不返回模型的实例

提问于
浏览
1

续集文档(http://docs.sequelizejs.com/en/v3/docs/raw-queries/)指出:

如果传递模型,则返回的数据将是该模型的实例 .

// Callee is the model definition. This allows you to easily map a query to a predefined model
sequelize.query('SELECT * FROM projects', { model: Projects }).then(function(projects){
  // Each record will now be a instance of Project
})

我已经为名为 agent 的资源定义了一个模型 .

module.exports = function(sequelize, DataTypes) {
   let Agent = sequelize.define('Agent', {
      responseStatus: DataTypes.STRING,
      agentnum: {
        type: DataTypes.STRING,
        primaryKey: true,
        allowNull: false,
        field : 'agentno'
      },
      fname :  {
        type: DataTypes.STRING,
        allowNull : false,
        field: 'fname'
      },
      lname : {
        type: DataTypes.STRING,
        allowNull: false,
        field : 'lname'
      }, 
      fullname : {
        type: DataTypes.STRING,
        allowNull : false,
        field: 'full_name'
      }, 
      status : {
        type: DataTypes.STRING,
        allowNull: false,
        field: 'business_status'
      }, 
      loginDate: DataTypes.DATE
  }, {
      freezeTableName: false,
      timestamps: false
  });

  return Agent;
};

当用我的查询调用 sequelize.query 并指定model:Agent时,我从sequelize中抛出一个错误:

TypeError: this.model.bulkBuild is not a function

堆栈指向 sequelize\lib\dialects\abstract\query.js:675 .

此错误仍然存在 until 我应用 sequelize.QueryTypes.RAW 的QueryType . 此时查询完成,我得到一个JSON响应,但它不是我的Agent模型的实例 . 来自sequelize查询的JSON响应包含应映射到的字段名称 .

我根据他们的快速样本(https://github.com/sequelize/express-example/blob/master/models/index.js)中的指示导入了我的模型(只有一个) . 模型集合显示我的代理模型已包含在内 .

import Sequelize from 'sequelize';
import config from './config';

export default callback => {
  const sequelize = new Sequelize(config.database, config.username, config.password, config.params);

  sequelize.sync().then(function() {
    let db = { }

    let agentModel = sequelize.import('model/agent.js');
    db[agentModel.name] = agentModel;

    db.sequelize = sequelize;
    db.Sequelize = Sequelize;

    db.sequelize.authenticate().then(function() {
      console.log('CONNECTION OK');
    });


    callback(db);

  }).catch(function(err) {
    console.log('FAILED TO CONNECT: ', err.message);
  });
}

我希望查询在运行该查询时返回Agent的实例(从POST调用到我的api) . 我正在使用MS SQL Server 2008 R2 .

任何输入都表示赞赏 . 谢谢 .

EDIT 1/30 这是生成sequelize对象并传入模型的代码 . 模型集合显示我的项目已添加,但它没有属性 .

connectDb: (function () {
        var sequelize;
        function createInstance() {
            var sequelizeInstance, connectedAndAuthenticated;
            sequelizeInstance = new Sequelize(config.database, config.username, config.password, config.params);
            connectedAndAuthenticated = sequelizeInstance.authenticate();
            connectedAndAuthenticated.sequelize = sequelizeInstance;
            connectedAndAuthenticated.Sequelize = Sequelize;

            var model = sequelizeInstance.import('../src/model/agent.js');


            return connectedAndAuthenticated;
        }
        return {
            getInstance : function () {
                if (!sequelize) {
                    sequelize = createInstance();
                }
                return sequelize;
            }
        };
    }())

EDIT 1/26 在操作 QueryTypes 之后,我发现了两件事 - 我无意中在数据库中使用模型名称(代理)创建了一个表,并且返回的对象的 tablename 属性值为空 . schematablename 由我指定,但查询是一个连接多个查询和表的存储过程,它不直接映射到名为 Agent 的数据库中的对象 . 话虽这么说,我的文档似乎建议 this does not and should not matter ,因为我正在创建自己的模型绑定到查询结果 .

2 回答

  • 0

    这似乎是一个简单的错字 . 我认为 Agent 实际上并未在您的范围内定义 . 我认为你应该传递 agentModel 或任何你绑定导入的内容 .

    let agentModel = sequelize.import('model/agent.js');    
    db.sequelize.query( "DECLARE @response VARCHAR(256); EXEC API_Login @agentnum = N'" + agentNum + "', @hashedPassword = '" + password + "', @response = @response OUTPUT; SELECT @response AS N'response'",{ model: agentModel, type: sequelize.QueryTypes.RAW}) .spread(function(Agent) { res.status(200).json(Agent); }) .catch(function(err) { handleError(err, res); });
    

    注意我正在使用 {model: agentModel, ...} 而不是 {model: Agent, ...} ,因为 Agent 在回调之外是未定义的 .

    如果 Agent 实际上不是模型而是其他东西(或未定义),则您的错误 TypeError: this.model.bulkBuild is not a function 非常有意义 .

    UPDATE

    您在下面的帖子的评论中提到:“我已同步模型 - 查询尝试创建表,而不是绑定到传入的代理模型”和“它不应该创建表” .

    为什么你认为那是这样的?在sync()期间创建表是Sequelize的正常行为 .

    我想你误解了Sequelize的作用 . 它在同步期间为每个注册的模型创建一个表 . 如果它无法创建该表,则可能返回无效模型,这就是您收到错误的原因 .

    模型明确地与各个数据库表绑定,这是Sequelize的基本行为 . 每个模型实例代表该表的一行 . 如果您正在使用存储过程,那么最好使用本机数据库库并定义自己的抽象层 .

    我确信你可以禁用和/或覆盖模型和底层数据库表之间的所有默认同步,但是在某个点或复杂性上,你基本上只编写了自己的抽象库,这样做会更干净 . 从头开始 .

    也许你可以按照你想要的方式使用Sequelize,但至少你不应该调用 sync() . 哪些副作用导致我无法说,但我可以说,除非你定义自己的 beforeSyncsync() 将始终在你的架构中创建一个表:

    Model.prototype.sync = function(options) {
      options = options || {};
      options.hooks = options.hooks === undefined ? true : !!options.hooks;
      options = Utils._.extend({}, this.options, options);
    
      var self = this
        , attributes = this.tableAttributes;
    
      return Promise.try(function () {
        if (options.hooks) {
          return self.runHooks('beforeSync', options);
        }
      }).then(function () {
        if (options.force) {
          return self.drop(options);
        }
      }).then(function () {
        return self.QueryInterface.createTable(self.getTableName(options), attributes, options, self);
      })
      ...
      }).return(this);
    };
    
  • 1

    sequelize doc令人困惑 . 我在解释你干净的方式使用sequelize put

    var models = require('../models');
    

    在你的代码文件中,确保models目录包含你在问题中告诉我的index.js以及Project model . be careful, other then correctly configured model there must not anything. 现在放

    models.sequelize.query("select 1 as val").then(function(result){
    console.log(result)
    })
    

    在您的代码中检查连接也应该使用find查询

    models.Projects.findAll().then(function(result){
        console.log(result)
        })
    

相关问题