Knex NodeJS 并插入数据库
Posted
技术标签:
【中文标题】Knex NodeJS 并插入数据库【英文标题】:Knex NodeJS and inserting into the database 【发布时间】:2015-05-09 18:57:10 【问题描述】:我是 nodejs 的新手,正在尝试设置 API 服务器,这是我的第一次尝试。我想使用 mysql 而不是 mongo db。
我的问题是 'knex('user').insert(email: req.body.email);'似乎不想保存到数据库中。
var dbConfig =
client: 'mysql',
connection:
host : 'localhost',
user : 'root',
password : '',
database : 'db_nodeapi'
;
var express = require('express'); // call express
var bodyParser = require('body-parser'); // call body-parser
var knex = require('knex')(dbConfig); // set up database connection
var app = express(); // define our app using express
app.use(bodyParser.urlencoded( extended: true )); // configure app to use bodyParser()
app.use(bodyParser.json()); // this will let us get the data from a POST
var router = express.Router(); // get an instance of the express Router
router.use(function(req, res, next) // middle ware for authentication
console.log(' -Logging- ');
next(); // continue to next route without stopping
);
router.get('/', function(req, res) // listen for a post on root
res.json( message: ' -Success- ' );
);
router.route('/user') // set up user route
.post(function(req, res) // listen for a post on user
console.log(' -Post -'); // report a post
knex('user').insert(email: req.body.email); // insert user into user table
res.json( success: true, message: 'ok' ); // respond back to request
);
app.use('/api', router); // register routes beginning with /api
var port = process.env.PORT || 8080; // set server port number
app.listen(port); // setup listener
console.log('Magic happens on port ' + port); // report port number chosen
问题是我无法将 knex 添加到数据库中!
CREATE TABLE IF NOT EXISTS `user` (
`id` int(11) NOT NULL,
`email` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;
这是数据库
【问题讨论】:
1) 您确定要发布电子邮件吗?如果将行 console.log(' -Post -') 更改为 console.log(' - Post - ' + req.body.email) 会发生什么? 2)你确定这是插入的语法吗?它看起来不像当前的文档,它使用更像 knex.insert(info).into('user') req.body.email 设置为 email 的发布值,我已经检查过了。 body-parser 处理了我被引导相信的这一点。 好的,到目前为止一切顺利。现在knex呢?您确定查询语法有效吗?例如,如果您从路由中删除代码并在需要 knex 之后添加一个快速行(类似): knex('user').insert(email:'AQuickTest@Example.com');发生什么了?然后如果你添加第二行像 knex.insert(email: 'AnotherTest@example.com).into('user') 会发生什么? knex.insert(email: req.body.email).into('user');什么都没试过,甚至没有错误。还尝试了 knex('user').insert(email:'AQuickTest@Example.com');在 var knex = ... 行之后。没有。试过 knex.insert(email: 'AnotherTest@example.com).into('user') ... 没有。两种都试过了……什么都没有。 嗯。可能是 knex 根本没有连接到数据库,也可能是它静默失败。 id 被指定为非空 - 它是否与序列或自动增量或其他东西相关联?或者这可能是一个失败点?顺便说一句 - 您可以将 'debug: true, ' 添加到 dbConfig 以将 SQL 语法和参数绑定输出到控制台。这也会很有帮助。 【参考方案1】:您的代码中的问题是您缺少“.then”语句,这会导致代码的实际执行。
knex('user').insert(email: req.body.email)
.then( function (result)
res.json( success: true, message: 'ok' ); // respond back to request
)
应该可以。由于 knex.js 的 insert 函数是一个 Promise,所以需要调用 .then() 才能真正调用它。
【讨论】:
knex 是否使用了某种惰性承诺?无论结果是否被处理,插入应该都会被执行(假设insert
返回一个常规的promise)。
是的。 Knex 需要一个 .then() 才能执行。
如果我想添加的不仅仅是电子邮件或多个对象,该怎么办?
我不再使用 knex,但我相信它们具有您可以使用的批量插入功能。您可以查看他们关于批量插入的文档:knexjs.org/#Utility-BatchInsert
也不适用于 await .. 他们应该做类似 knex(...).insert(...).execute() 的事情,它检索并执行一个承诺,从而使用等待并且可以添加 .then 如果需要【参考方案2】:
有人已经给出了解决方案。我在这里讲一下为什么添加then语句可以解决这个问题。
其实then、catch语句都可以。请参考 knex 文档(http://knexjs.org/#Interfaces-then),其中提到:
强制当前查询构建器链进入承诺状态。
所以select、update、insert等只是查询语句生成器,你必须使用then 或 catch 将其转换为 Promise 状态。
示例如下:
knex('user').insert(email: req.body.email) //not working
knex('user').insert(email: req.body.email).then(()=>) //working
knex('user').insert(email: req.body.email).catch(()=>) //working
.then(()=>
knex('user').insert(email: req.body.email) //not working
knex('user').insert(email: req.body.email).then(()=>) //working
knex('user').insert(email: req.body.email).catch(()=>) //working
return knex('user').insert(email: req.body.email) //working
)
【讨论】:
【参考方案3】:曾经遇到过类似的问题,试试这个:
//...
router.route('/user').post(function(req, res)
knex('user').insert(email: req.body.email).then(function(ret)
res.json( success: true, message: 'ok'/*,ret:ret*/);
);
);
//...
【讨论】:
以上是关于Knex NodeJS 并插入数据库的主要内容,如果未能解决你的问题,请参考以下文章
错误 [ERR_HTTP_HEADERS_SENT]:在尝试使用 knex 进行验证和插入时,无法在将标头发送到客户端后设置标头