升级到 8.0
¥Upgrading to 8.0
node-postgres 8.0 引入了对 SSL 验证连接的重大更改。如果你使用 SSL 连接并使用
¥node-postgres at 8.0 introduces a breaking change to ssl-verified connections. If you connect with ssl and use
const client = new Client({ ssl: true })
并且服务器的 SSL 证书是自签名的,从 node-postgres 8.0 开始连接将失败。要保留现有行为,请将调用修改为
¥and the server's SSL certificate is self-signed, connections will fail as of node-postgres 8.0. To keep the existing behavior, modify the invocation to
const client = new Client({ ssl: { rejectUnauthorized: false } })
其余更改相对较小,不太可能引起问题;有关完整详细信息,请参阅 公告。
¥The rest of the changes are relatively minor and unlikely to cause issues; see the announcement for full details.
升级到 7.0
¥Upgrading to 7.0
node-postgres 7.0 对公共 API 引入了一些重大的重大变化。
¥node-postgres at 7.0 introduces somewhat significant breaking changes to the public API.
节点版本支持
¥node version support
从 pg@7.0
开始,支持的节点的最早版本将是 node@4.x LTS
。对 node@0.12.x
和 node@.10.x
的支持被删除,并且模块将无法工作,因为它依赖于旧版本节点中不可用的新 es6 功能。
¥Starting with pg@7.0
the earliest version of node supported will be node@4.x LTS
. Support for node@0.12.x
and node@.10.x
is dropped, and the module wont work as it relies on new es6 features not available in older versions of node.
pg 单例
¥pg singleton
过去,包中的根 pg
对象上附加了一个单例池管理器。此单例可用于通过调用 pg.connect
自动配置连接池。此 API 给用户带来了很多困惑。它还引入了一个不透明的模块管理单例,很难推断、调试、容易出错且不灵活。从 pg@6.0 开始,方法的文档已被删除,从 pg@6.3 开始,方法已被弃用并显示警告消息。
¥In the past there was a singleton pool manager attached to the root pg
object in the package. This singleton could be used to provision connection pools automatically by calling pg.connect
. This API caused a lot of confusion for users. It also introduced a opaque module-managed singleton which was difficult to reason about, debug, error-prone, and inflexible. Starting in pg@6.0 the methods' documentation was removed, and starting in pg@6.3 the methods were deprecated with a warning message.
如果你的应用仍然依赖这些,它们将在 pg@7.0
中消失。为了迁移,你可以执行以下操作:
¥If your application still relies on these they will be gone in pg@7.0
. In order to migrate you can do the following:
// old way, deprecated in 6.3.0:
// connection using global singleton
pg.connect(function (err, client, done) {
client.query(/* etc, etc */)
done()
})
// singleton pool shutdown
pg.end()
// ------------------
// new way, available since 6.0.0:
// create a pool
var pool = new pg.Pool()
// connection using created pool
pool.connect(function (err, client, done) {
client.query(/* etc, etc */)
done()
})
// pool shutdown
pool.end()
node-postgres 附带由 pg-pool 提供的内置池对象,该对象已由 pg.connect
和 pg.end
方法内部使用。迁移到用户管理的池(或池集)允许你更直接地控制它们的设置及其生命周期。
¥node-postgres ships with a built-in pool object provided by pg-pool which is already used internally by the pg.connect
and pg.end
methods. Migrating to a user-managed pool (or set of pools) allows you to more directly control their set up their life-cycle.
client.query(...).on
在 pg@7.0
之前,client.query
方法总是返回查询的实例。查询实例是一个事件触发器,接受回调,也是一个 promise。一些问题...
¥Before pg@7.0
the client.query
method would always return an instance of a query. The query instance was an event emitter, accepted a callback, and was also a promise. A few problems...
-
单个对象上的流控制选项太多令人困惑
¥too many flow control options on a single object was confusing
-
事件触发器
.on('error')
与 promise.catch
混合不好¥event emitter
.on('error')
does not mix well with promise.catch
-
row
事件是常见的错误来源:它看起来像一个流,但不支持背压,误导用户尝试管道结果或在事件触发器中处理它们以获得所需的性能提升。¥the
row
event was a common source of errors: it looks like a stream but has no support for back-pressure, misleading users into trying to pipe results or handling them in the event emitter for a desired performance gain. -
使用
.done
和.error
触发器对进行每个查询的错误处理很麻烦,并且从client.query
返回触发器表明可以鼓励这种模式:不是。¥error handling with a
.done
and.error
emitter pair for every query is cumbersome and returning the emitter fromclient.query
indicated this sort of pattern may be encouraged: it is not.
从 pg@7.0
开始,返回值 client.query
将取决于你传递给方法的内容:我认为这与大多数节点库处理回调/promise 组合的方式更加一致,我希望它会使 "正常工作" :tm:感觉更好,同时减少事件触发器/回调组合的表面积和意外。
¥Starting with pg@7.0
the return value client.query
will be dependent on what you pass to the method: I think this aligns more with how most node libraries handle the callback/promise combo, and I hope it will make the "just works" :tm: feeling better while reducing surface area and surprises around event emitter / callback combos.
带回调的 client.query
¥client.query with a callback
const query = client.query('SELECT NOW()', (err, res) => {
/* etc, etc */
})
assert(query === undefined) // true
如果你将回调传递给方法,client.query
将返回 undefined
。这将流控制限制为与几乎所有节点核心 API 一致的回调。
¥If you pass a callback to the method client.query
will return undefined
. This limits flow control to the callback which is in-line with almost all of node's core APIs.
不带回调的 client.query
¥client.query without a callback
const query = client.query('SELECT NOW()')
assert(query instanceof Promise) // true
assert(query.on === undefined) // true
query.then((res) => /* etc, etc */)
如果你不传递回调,client.query
将返回 Promise
的实例。这不会是查询实例,也不会是事件触发器。这与大多数基于 promise 的 API 在节点中的工作方式一致。
¥If you do not pass a callback client.query
will return an instance of a Promise
. This will not be a query instance and will not be an event emitter. This is in line with how most promise-based APIs work in node.
client.query(Submittable)
client.query
始终接受任何具有 .submit
方法的对象。在这种情况下,客户端在对象上调用 .submit
,将执行责任委托给它。在这种情况下,客户端还会返回传递的实例。这是 pg-cursor 和 pg-query-stream 的工作方式。因此,如果你出于某种原因需要在查询中使用事件触发器功能,这仍然是可能的,因为 Query
是 Submittable
的一个实例:
¥client.query
has always accepted any object that has a .submit
method on it. In this scenario the client calls .submit
on the object, delegating execution responsibility to it. In this situation the client also returns the instance it was passed. This is how pg-cursor and pg-query-stream work. So, if you need the event emitter functionality on your queries for some reason, it is still possible because Query
is an instance of Submittable
:
import pg from 'pg'
const { Client, Query } = pg
const query = client.query(new Query('SELECT NOW()'))
query.on('row', (row) => {})
query.on('end', (res) => {})
query.on('error', (res) => {})
Query
被视为 node-postgres API 的公共、记录部分,并且将无限期地支持此形式。
¥Query
is considered a public, documented part of the API of node-postgres and this form will be supported indefinitely.
注意:我使用 node-postgres 构建应用已有近 7 年了。在那段时间里,我从未使用事件触发器 API 作为执行查询的主要方式。我以前使用回调,现在我使用 async/await。如果你需要流式传输结果,我强烈建议你使用 pg-cursor 或 pg-query-stream,而不是查询对象作为事件触发器。
¥note: I have been building apps with node-postgres for almost 7 years. In that time I have never used the event emitter API as the primary way to execute queries. I used to use callbacks and now I use async/await. If you need to stream results I highly recommend you use pg-cursor or pg-query-stream and not the query object as an event emitter.