2017-01-24 6 views
1

sequelize документации (http://docs.sequelizejs.com/en/v3/docs/raw-queries/) гласит:Sequelize не возвращает экземпляр модели

If you pass a model the returned data will be instances of that model.

// 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 с моим запросом и указав модель: Agent, я получаю сообщение об ошибке, брошенной из sequelize:

TypeError: this.model.bulkBuild is not a function

точки стеки в sequelize\lib\dialects\abstract\query.js:675.

Эта ошибка сохраняется до Я применяю QueryType от sequelize.QueryTypes.RAW. На этом этапе запрос завершается, и я получаю ответ JSON, но это не экземпляр моей модели агента. Ответ JSON от запроса sequelize содержит имена полей, к которым необходимо сопоставить.

Я импортировал свою модель (ее только одну) в соответствии с указаниями, найденными в их экспресс-образце (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); 
    }); 
} 

Я хочу, чтобы запрос, чтобы вернуть экземпляр агента, когда этот запрос выполняется (вызывается из 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 значение свойства пустое. schema и tablename указаны мной, но запрос, являющийся хранимой процедурой, которая объединяет несколько запросов и таблиц, напрямую не отображает объект в моей базе данных с именем Agent. При этом документация для меня, по-видимому, предполагает, что это не имеет значения и не должно иметь значения, так как я создаю свою собственную модель, связанную с результатом запроса.

+0

что ваш запрос? – Adam

+0

'db.sequelize .query ( " DECLARE @response VARCHAR (256); EXEC API_Login @agentnum = N '"+ agentNum +"', @hashedPassword = '"+ password +"', @response = @response OUTPUT SELECT @response AS N'response '", {model: Agent, type: sequelize.QueryTypes.RAW}) .spread (функция (агент) { res.status (200) .json (агент); }) .catch (function (err) { handleError (err, res); }); '- Это вызванная хранимая процедура. –

+0

что делать, если вы делаете 'type: sequelize.QueryTypes.SELECT'? – Adam

ответ

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 не определено за пределами обратного вызова.

Ваша ошибка TypeError: this.model.bulkBuild is not a function имеет смысл, если Agent на самом деле не модель, а что-то еще (или неопределенное).

UPDATE

Вы упоминаете в комментариях по почте ниже, что: «Я синхронизируюсь модель - запрос пытается создать таблицу, вместо привязки к переданным в модели агента» и «Он должен не создавать таблицу ".

Почему вы думаете, что это так? Создание таблицы во время синхронизации() - нормальное поведение для Sequelize.

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

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

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

Возможно, вы можете использовать Sequelize так, как хотите, но по крайней мере вы не должны звонить sync(). Какие побочные эффекты, что приводит к не могу сказать, но я могу сказать, что если вы не определить свой собственный beforeSync крючок sync() всегда будет создавать таблицу в вашей схеме:

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); 
}; 
+0

ошибка сохраняется. Я должен был уточнить, что раньше я это делал. Сначала я понял, что это имя модели в коллекции (оно определено как «Агент», поэтому я думал, что JSON хочет имя определенной модели, а не экземпляр), но когда я его изменил, я получаю то же самое исключение для каждого другого типа запроса, кроме Raw, который возвращает raw json. –

+0

Вы пробовали console.debug (agentModel), чтобы узнать, что это на самом деле? Имеет ли метод bulkBuild? Кроме того, если библиотека действительно хочет _name_ агента (и я не уверен, что это так), то это будет строка '' Agent '', а не переменная' Agent' (которая, предположительно, не определена) – SpliFF

+0

Да. Это объект JSON, который выглядит следующим образом: '{Агент: Агент}'. Никакие свойства не назначены ему. Он загружает файл модели, потому что, если я намеренно ошибаюсь, приложение вызывает исключение, но в остальном это все, что я заметил об этом. –

1

sequelize док путает .Я объяснить вам чистый способ использовать sequelize положить

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

в файле кода убедитесь, что каталог моделей содержат index.js, как вы сказали мне в вашем вопросе, а также проект модель. Будьте осторожны, другая, то правильно настроенная модель не должна ничего. Теперь поместите

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

в коде проверить соединение также следует использовать найти запрос как

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

Да, это смущает!Но это не приемлемый ответ. Я могу подключиться к существующему экземпляру SQL Server, и я могу запросить его. То, что я не могу понять или сделать, - это привязать мою существующую модель (которая находится в каталоге моделей) к выходу хранимой процедуры, даже если документация, похоже, предполагает, что это возможно, передав имя вашей модели. –

+1

данные автоматически связываются с вызовом модели с именем модели. я не понимаю, что вы сбиваете с толку. но я думаю, что вы ищете метод класса, getter & setter для манипулирования данными при хранении или извлечения – shivshankar

+0

«данные автоматически связываются с вызовом модели с именем модели» - я говорю, что я это сделал. Я попытался как вручную добавить модель в коллекцию моделей, так и указать модель в запросе, но она не связывается автоматически. Модель загружается, когда я проверяю коллекцию. Вместо этого он возвращает только результат запроса. Это не находка - идея, которую я прочитал в документации, - это просто определить вашу модель, и когда вы ее запросите, она будет привязана к предоставленной модели. Это не делает это прямо сейчас. Не понимаю ли я документацию? –