2015-06-28 53 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'和你的路由文件。您的快速應用程序創建過程如何AFAIK,Express 4不再有項目生成器。 – robertklep

+0

我使用這個獲取事務:var sequelize = models.sequelize; \t \t \t sequelize.transaction(函數(T){} ... 但還是不知道如何提交和回滾在錯誤的情況下,嘗試這種whay:})。趕上(功能(E){ \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來循環你的數組。續訂需要始終設置自動提交的承諾。 你的t.commit()在哪裏? –