接口

Knex.js provides several options to deal with query output. 查询构建器、模式构建器和原始构建器上存在以下方法:

Knex.js provides several options to deal with query output. The following methods are present on the query builder, schema builder, and the raw builder:

Promise

Promise 是在 knex 中处理查询的首选方式,因为它们允许你从履行处理程序返回值,这些值反过来又成为 promise 的值。 Promise 的主要好处是能够捕获抛出的错误而不会使节点应用崩溃,使你的代码表现得像同步代码中的 .try / .catch / .finally

Promises are the preferred way of dealing with queries in knex, as they allow you to return values from a fulfillment handler, which in turn become the value of the promise. The main benefit of promises are the ability to catch thrown errors without crashing the node app, making your code behave like a .try / .catch / .finally in synchronous code.

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

.then(onFulfilled, [onRejected])

.then(onFulfilled, [onRejected])

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

Coerces the current query builder chain into a promise state, accepting the resolve and reject handlers as specified by the Promises/A+ spec. As stated in the spec, more than one call to the then method for the current query chain will resolve with the same value, in the order they were called; the query will not be executed multiple times.

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

.catch(onRejected)

.catch(onRejected)

Coerces the current query builder into a promise state, catching any error thrown by the query, the same as calling .then(null, onRejected).

Coerces the current query builder into a promise state, catching any error thrown by the query, the same as calling .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);
  });

回调

asCallback

.asCallback(callback)

.asCallback(callback)

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

If you'd prefer a callback interface over promises, the asCallback function accepts a standard node style callback for executing the query chain. Note that as with the then method, subsequent calls to the same query chain will return the same result.

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 模块。 如果你希望使用 pgnative 方言的流,请注意,结果不会在收到时进行流式传输,而是在整个结果集返回后进行流式传输。 在 HTTP 服务器上,如果请求中止,请确保 手动关闭你的流

Streams are a powerful way of piping data through as it comes in, rather than all at once. You can read more about streams here at substack's stream handbook. See the following for example uses of stream & pipe. If you wish to use streams with PostgreSQL, you must also install the pg-query-stream module. If you wish to use streams with the pgnative dialect, please be aware that the results will not be streamed as they are received, but rather streamed after the entire result set has returned. On an HTTP server, make sure to manually close your streams if a request is aborted.

stream

.stream([options], [callback])

.stream([options], [callback])

如果使用回调调用,则回调将传递到流并返回 promise。 否则,返回可读流。
当流作为 iterator 消耗时,如果循环以 breakreturnthrow 终止,则流将被销毁。 换句话说,迭代流将完全消耗该流。

If called with a callback, the callback is passed the stream and a promise is returned. Otherwise, the readable stream is returned.
When the stream is consumed as an iterator, if the loop terminates with a break, return, or a throw, the stream will be destroyed. In other terms, iterating over a stream will consume the stream fully.

// Retrieve the stream:
const stream = knex.select('*')
  .from('users')
  .stream();
stream.pipe(writableStream);
// With options:
const stream = knex.select('*')
  .from('users')
  .stream({highWaterMark: 5});
stream.pipe(writableStream);
// Use as an iterator
const stream = knex.select('*')
  .from('users')
  .stream();

for await (const row of stream) {
  /* ... */
}
// Use as a promise:
const 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

.pipe(writableStream)

.pipe(writableStream)

将当前查询的流传输到 writableStream。

Pipe a stream for the current query to a writableStream.

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

事件

query

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

A query event is fired just before a query takes place, providing data about the query, including the connection's __knexUid / __knexTxId properties and any other information about the query as described in toSQL. Useful for logging all queries throughout your application.

knex.select('*')
  .from('users')
  .on('query', function(data) {
    app.log(data);
  })
  .then(function() {
    // ...
  });

query-error

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

A query-error event is fired when an error occurs when running a query, providing the error object and data about the query, including the connection's __knexUid / __knexTxId properties and any other information about the query as described in toSQL. Useful for logging all query errors throughout your application.

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.
  });

query-response

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

A query-response event is fired when a successful query has been run, providing the response of the query and data about the query, including the connection's __knexUid / __knexTxId properties and any other information about the query as described in toSQL, and finally the query builder used for the query.

knex.select('*')
  .from('users')
  .on('query-response', function(response, obj, builder) {
    // ...
  })
  .then(function(response) {
    // Same response as the emitted event
  })
  .catch(function(error) { });

start

在编译查询构建器之前会触发 start 事件。

A start event is fired right before a query-builder is compiled.

信息

虽然此事件可用于在编译之前更改构建器状态,但不建议这样做。 未来的目标包括以不同的方式实现这一点,例如钩子。

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()

.toString()

返回一个查询字符串数组,其中根据绑定等填写了正确的值。对于调试很有用,但不应用于创建针对数据库运行它们的查询。

Returns an array of query strings filled out with the correct values based on bindings, etc. Useful for debugging, but should not be used to create queries for running them against DB.

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

// Outputs: console.log(toStringQuery); 
// select * from "users" where "id" = 1

toSQL

.toSQL() .toSQL().toNative()

.toSQL()
.toSQL().toNative()

返回一个查询字符串数组,其中根据绑定等填写了正确的值。对于调试和构建查询以使用数据库驱动程序手动运行它们很有用。 .toSQL().toNative() 以方言格式输出带有 sql 字符串和绑定的对象,其方式与 knex 内部将它们发送到底层数据库驱动程序的方式相同。

Returns an array of query strings filled out with the correct values based on bindings, etc. Useful for debugging and building queries for running them manually with DB driver. .toSQL().toNative() outputs object with sql string and bindings in a dialects format in the same way that knex internally sends them to underlying DB driver.

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',
// }