2015-06-28 1 views
1

Я пытаюсь сделать запрос на отдых с помощью sequelize сделки, к сожалению, она не работает:Создание sequelize транзакции внутри Экспресс маршрутизатора

undefined is not a function 

Это означает, что sequelize.transaction не определено, sequelize импортируется, но не созданный для моего внутреннего маршрута:

router.post('/', secret.ensureAuthorized, function(req, res) { 

    var sequelize = models.sequelize; 
    var newpost; 

    sequelize.transaction({autocommit: false}, function (t) {  

     return models.post.build().updateAttributes({ 
       title: req.body.title, 
       shortdescription: req.body.description.substring(0,255), 
       description: req.body.description, 
       titleImage: req.body.titleImage, 
       link: req.body.link, 
       userid: req.body.userid 
      }, {transaction: t}).then(function(post){ 
       newpost = post; 
       // create categories 
       var tags = req.body.categories; 

       models.hashtag.bulkCreate(tags, {transaction: t}).then(function(){ 
        newpost.setTags(tags, {transaction: t}); 
       });   
     }); 


    }).then(function (result) { 
     // Transaction has been committed 
     // result is whatever the result of the promise chain returned to the transaction callback is 
     if (newpost) { 
      res.json(newpost); 
     } 
     console.log(result); 
    }).catch(function (e) { 
     // Transaction has been rolled back 
     // err is whatever rejected the promise chain returned to the transaction callback is 
     throw e; 
    }); 
}); 

Мои модели работают без проблем, а экспресс-маршруты работают, но не с транзакциями.

Мой пакет JSON

{ 
    "name": "myapp", 
    "version": "0.0.1", 
    "private": true, 
    "scripts": { 
    "start": "node ./bin/www" 
    }, 
    "dependencies": { 
    "body-parser": "~1.12.4", 
    "cookie-parser": "~1.3.5", 
    "debug": "~2.2.0", 
    "express": "~4.12.4", 
    "jade": "~1.9.2", 
    "morgan": "~1.5.3", 
    "serve-favicon": "~2.2.1", 
    "jsonwebtoken": "^5.0.2", 
    "pg": "^4.4.0", 
    "pg-hstore": "^2.3.2", 
    "crypto-js": "^3.1.5", 
    "sequelize": "^3.2.0" 
    } 
} 

Мой index.js работает тоже хорошо, но не знаете, как пройти тот же экземпляр sequelize здесь для экспресс-маршрутов:

var Sequelize = require('sequelize'); 
var config = require('../config'); // we use node-config to handle environments 
var fs  = require("fs"); 
var path  = require("path"); 
var models = require('../models'); 
// initialize database connection 
var sequelize = new Sequelize(
    config.database.name, 
    config.database.username, 
    config.database.password, { 
     dialect: 'postgres', 
     host: config.database.host, 
     port: config.database.port, 
     autoIncrement: true, 
     omitNull: true, 
     freezeTableName: true, 
     pool: { 
     max: 15, 
     min: 0, 
     idle: 10000 
     }, 
}); 

var db  = {}; 

fs 
    .readdirSync(__dirname) 
    .filter(function(file) { 
    return (file.indexOf(".") !== 0) && (file !== "index.js"); 
    }) 
    .forEach(function(file) { 
    var model = sequelize["import"](path.join(__dirname, file)); 
    db[model.name] = model; 
    }); 

Object.keys(db).forEach(function(modelName) { 
    if ("associate" in db[modelName]) { 
    db[modelName].associate(db); 
    } 
}); 

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

sequelize.sync({ 
    force: true 
}).then(function(){ 
// load batch 
    if (process.env.BATCH) { 
     console.log("loading batch"); 
     var batch = require("../config/batch"); 
     batch.loadPosts(); 
    } 
}); 


module.exports = db; 

наилучшими пожеланиями ,

UPDATE Я изменил код, как описано выше. Теперь моя ошибка:

Unhandled rejection Error: commit has been called on this transaction(c457e532-b 
164-43dc-9b0e-432be031fe36), you can no longer use it 

Я использую базу данных Postgres.

ответ

0

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

Однако вы импортируете глобальный модуль sequelize, а не ваш местный. Вы должны использовать относительный путь, чтобы сделать это:

router.post('/', function(req, res) { 
    var sequelize = require('./sequelize'); 

    sequelize.transaction(function(t){ 

     console.log('transaction openned'+t); 

    }); 
}); 

(что предполагает, что файл sequelize.js находится в том же каталоге, что и файл обработчика маршрута является, если нет, то вы должны изменить ./ часть)

+0

привет Роберт, на самом деле у меня нет никаких sequelize.js, я пытаясь получить такое же соединение, которое я определил в своих моделях index.js, он создается там. – lambdapool

+0

@JoseCarlos в этом случае вам следует подумать о переносе материала базы данных в отдельный файл и 'require()' как из вашего файла 'index.js', так и вашего файла маршрутов. Как было создано ваше приложение Express? AFAIK, Express 4 больше не имеет генератора проекта. – robertklep

+0

Я получаю транзакцию, используя это: var sequelize = models.sequelize; \t \t \t sequelize.transaction (функция (т) {} ... , но до сих пор не понимаю, как совершать и откат в случае ошибки, пытаясь это whay:}). Улов (функция (е) { \t // сделка была откат \t // эээ является то, что отвергнуто обещание цепь возвращается в обратный вызов транзакции является \t \t возвращение t.rollback() \t.затем (функция() { \t throw e; \t}); \t}); , но говорит, что t не определено. – lambdapool

1

Это мое окончательное решение, я не знал о возвращении этих обещаний, теперь я могу сделать это так:

var sequelize = models.sequelize; 
    var newpost; 
    // create categories 
    var tags = req.body.categories; 
    sequelize.transaction({autocommit: false}, function (t) {  

     return models.post.build().updateAttributes({ 
       title: req.body.title, 
       shortdescription: req.body.description.substring(0,255), 
       description: req.body.description, 
       titleImage: req.body.titleImage, 
       link: req.body.link, 
       userid: req.body.userid 
      }, {transaction: t}).then(function(post){ 
       newpost = post; 
       for (var i = 0; i < tags.length;i++) { 

        // ({where: {username: 'sdepold'}, defaults: {job: 'Technical Lead JavaScript'}}) 

       return models.hashtag.findOrCreate(
         {where: {description: tags[i].description}, 
         defaults: {description: tags[i].description}, 
         transaction: t}).spread(function(tag, created) { 
         return newpost.addTag(tag, {transaction: t}); 
        });    
       } 
      }); 

    }).then(function (result) { 
     // Transaction has been committed 
     // result is whatever the result of the promise chain returned to the transaction callback is 
     if (newpost) { 
      res.json(newpost); 
     } 
     console.log(result); 
    }).catch(function (e) { 
     // Transaction has been rolled back 
     // err is whatever rejected the promise chain returned to the transaction callback is 
     res.status(500).send({ 
       type: false, 
       data: e 
      });  
     throw e; 
    }); 
+1

Вместо того, чтобы зацикливать и возвращать, используйте некоторый асинхронный Foreach для цикла вашего массива. Sequelize всегда нужно обещание установить autocommit. Адрес: t.commit()? –