效用

为了方便起见,knex库提供了一组实用程序。


批量插入

该batchInsert实用程序将插入一个批次包裹在事务内的行(其被自动创建的,除非明确地给出了使用一个交易交易),在给定的chunkSize。


它主要设计用于要在表中插入数千行的情况。


默认情况下,chunkSize设置为1000。


BatchInsert还允许使用事务处理返回值并提供交易。


var rows = [{...}, {...}];

var chunkSize = 30;

knex.batchInsert('TableName', rows, chunkSize)

  .returning('id')

  .then(function(ids) { ... })

  .catch(function(error) { ... });


knex.transaction(function(tr) {

  return knex.batchInsert('TableName', rows, chunkSize)

    .transacting(tr)

  })

  .then(function() { ... })

  .catch(function(error) { ... });

介面

Knex.js提供了几种处理查询输出的选项。查询构建器,模式构建器和原始构建器上存在以下方法:


承诺

承诺是处理knex中查询的首选方式,因为它们使您可以从实现处理程序中返回值,这又成为承诺的值。promise的主要好处是能够在不使节点应用程序崩溃的情况下捕获引发的错误,从而使您的代码在同步代码中的行为像.try / .catch / .finally。


knex.select('name')

  .from('users')

  .where('id', '>', 20)

  .andWhere('id', '<', 200)

  .limit(10)

  .offset(x)

  .then(function(rows) {

    return _.pluck(rows, 'name');

  })

  .then(function(names) {

    return knex.select('id').from('nicknames').whereIn('nickname', names);

  })

  .then(function(rows) {

    console.log(rows);

  })

  .catch(function(error) {

    console.error(error)

  });

然后 -.then(onFulfilled, [onRejected])

将当前查询构建器链强制为promise状态,接受Promises / A +规范指定的resolve和拒绝处理程序。如规范中所述,对当前查询链的then方法的多个调用将以相同的值(以被调用的顺序)进行解析;该查询将不会多次执行。


knex.select('*')

  .from('users')

  .where({name: 'Tim'})

  .then(function(rows) {

    return knex.insert({user_id: rows[0].id, name: 'Test'}, 'id').into('accounts');

  })

  .then(function(id) {

    console.log('Inserted Account ' + id);

  })

  .catch(function(error) { console.error(error); });

抓 -.catch(onRejected)

将当前查询生成器强制转换为Promise状态,捕获由查询引发的任何错误,与调用.then(null,onRejected)相同。


return knex.insert({id: 1, name: 'Test'}, 'id')

  .into('accounts')

  .catch(function(error) {

    console.error(error);

  }).then(function() {

    return knex.select('*')

      .from('accounts')

      .where('id', 1);

  }).then(function(rows) {

    console.log(rows[0]);

  })

  .catch(function(error) {

    console.error(error);

  });

返回 -.return(value)

调用.then(function(){返回值})的简写。


// Without return:

knex.insert(values).into('users')

  .then(function() {

    return {inserted: true};

  });


knex.insert(values).into('users').return({inserted: true});

回呼

asCallback —.asCallback(callback)

如果您更希望使用回调接口而不是Promise,则asCallback函数接受用于执行查询链的标准节点样式的回调。请注意,与then方法一样,对同一查询链的后续调用将返回相同的结果。


knex.select('name').from('users')

  .where('id', '>', 20)

  .andWhere('id', '<', 200)

  .limit(10)

  .offset(x)

  .asCallback(function(err, rows) {

    if (err) return console.error(err);

    knex.select('id').from('nicknames')

      .whereIn('nickname', _.pluck(rows, 'name'))

      .asCallback(function(err, rows) {

        if (err) return console.error(err);

        console.log(rows);

      });

  });

流是一种通过管道传递数据的强大方法,而不是一次全部。您可以在substack的流手册中阅读有关流的更多信息。有关流和管道的用法示例,请参见以下内容。如果您希望在PostgreSQL中使用流,则还必须安装pg-query-stream模块。在HTTP服务器上,如果请求中止,请确保手动关闭流。


流 -.stream([options], [callback])

如果使用回调进行调用,则回调将通过流并返回promise。否则,返回可读流。


// Retrieve the stream:

var stream = knex.select('*').from('users').stream();

stream.pipe(writableStream);


// With options:

var stream = knex.select('*').from('users').stream({highWaterMark: 5});

stream.pipe(writableStream);


// Use as a promise:

var stream = knex.select('*').from('users')

  .where(knex.raw('id = ?', [1]))

  .stream(function(stream) {

    stream.pipe(writableStream);

  })

  .then(function() { // ... })

  .catch(function(e) { console.error(e); });

管道 —.pipe(writableStream)

将当前查询的流通过管道传输到writableStream。


var stream = knex.select('*').from('users').pipe(writableStream);

大事记

询问

查询事件将在查询发生之前立即触发,提供有关查询的数据,包括连接的__knexUid/ __knexTxId属性以及toSQL中描述的有关查询的任何其他信息。对于记录整个应用程序中的所有查询很有用。


knex.select('*')

  .from('users')

  .on('query', function(data) {

    app.log(data);

  })

  .then(function() {

    // ...

  });

查询错误

运行查询时发生错误时,将引发查询错误事件,并提供错误对象和有关查询的数据,包括连接的__knexUid/ __knexTxId属性以及toSQL中描述的有关查询的任何其他信息。对于记录整个应用程序中的所有查询错误很有用。


knex.select(['NonExistentColumn'])

  .from('users')

  .on('query-error', function(error, obj) {

    app.log(error);

  })

  .then(function() { // ... })

  .catch(function(error) {

    // Same error object as the query-error event provides.

  });

查询-响应

运行成功的查询后,将触发查询响应事件,以提供查询的响应和有关查询的数据,包括连接的__knexUid/ __knexTxId属性以及toSQL中描述的有关查询的任何其他信息,最后使用的查询构建器用于查询。


knex.select('*')

  .from('users')

  .on('query-response', function(response, obj, builder) {

    // ...

  })

  .then(function(response) {

    // Same response as the emitted event

  })

  .catch(function(error) { });

开始

start在编译查询生成器之前会触发一个事件。注意:虽然可以使用此事件在编译之前更改构建器的状态,但不建议这样做。未来的目标包括以其他方式执行此操作的方法,例如挂钩。


knex.select('*')

  .from('users')

  .on('start', function(builder) {

    builder

    .where('IsPrivate', 0)

  })

  .then(function(Rows) {

    //Only contains Rows where IsPrivate = 0

  })

  .catch(function(error) { });

其他

toString —.toString()

返回一个查询字符串数组,该数组用基于绑定等的正确值填充。对于调试很有用,但不应用于创建针对DB运行查询的查询。


var toStringQuery = knex.select('*').from('users').where('id', 1).toString();


// Outputs: console.log(toStringQuery); 

// select * from "users" where "id" = 1

toSQL —.toSQL() and toSQL().toNative()

返回基于绑定等填充正确值的查询字符串数组。对于调试和构建查询以通过DB驱动程序手动运行它们很有用。.toSQL().toNative()以方言格式输出带有sql字符串和绑定的对象,方法与knex在内部将其发送到基础DB驱动程序的方式相同。


knex.select('*').from('users')

  .where(knex.raw('id = ?', [1]))

  .toSQL()

// Outputs:

// {

//   bindings: [1],

//   method: 'select',

//   sql: 'select * from "users" where id = ?',

//   options: undefined,

//   toNative: function () {}

// }


knex.select('*').from('users')

  .where(knex.raw('id = ?', [1]))

  .toSQL().toNative()

// Outputs for postgresql dialect:

// {

//   bindings: [1],

//   sql: 'select * from "users" where id = $1',

// }