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语句可以解决这个问题。

其实thencatch语句都可以。请参考 knex 文档(http://knexjs.org/#Interfaces-then),其中提到:

强制当前查询构建器链进入承诺状态。

所以selectupdateinsert等只是查询语句生成器,你必须使用thencatch 将其转换为 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 并插入数据库的主要内容,如果未能解决你的问题,请参考以下文章

使用 Knex.js 进行多行插入

插入后 Knex 解析空集

使用 Knex 和 PG 插入多行

仅当使用 knex 唯一时才插入

Knex 不返回插入 ID

错误 [ERR_HTTP_HEADERS_SENT]:在尝试使用 knex 进行验证和插入时,无法在将标头发送到客户端后设置标头