mirror of
https://github.com/brianc/node-postgres.git
synced 2026-01-18 15:55:05 +00:00
115 lines
5.5 KiB
Markdown
115 lines
5.5 KiB
Markdown
---
|
|
title: Upgrading
|
|
slug: /guides/upgrading
|
|
---
|
|
|
|
# Upgrading to 8.0
|
|
|
|
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 })
|
|
```
|
|
|
|
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](/announcements#2020-02-25) for full details.
|
|
|
|
# Upgrading to 7.0
|
|
|
|
node-postgres at 7.0 introduces somewhat significant breaking changes to the public API.
|
|
|
|
## node version support
|
|
|
|
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 singleton
|
|
|
|
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.
|
|
|
|
If your application still relies on these they will be _gone_ in `pg@7.0`. In order to migrate you can do the following:
|
|
|
|
```js
|
|
// 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 ships with a built-in pool object provided by [pg-pool](https://github.com/brianc/node-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
|
|
|
|
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
|
|
- event emitter `.on('error')` does not mix well with promise `.catch`
|
|
- 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.
|
|
- error handling with a `.done` and `.error` emitter pair for every query is cumbersome and returning the emitter from `client.query` indicated this sort of pattern may be encouraged: it is not.
|
|
|
|
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 with a callback
|
|
|
|
```js
|
|
const query = client.query('SELECT NOW()', (err, res) => {
|
|
/* etc, etc */
|
|
})
|
|
assert(query === undefined) // true
|
|
```
|
|
|
|
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 without a callback
|
|
|
|
```js
|
|
const query = client.query('SELECT NOW()')
|
|
assert(query instanceof Promise) // true
|
|
assert(query.on === undefined) // true
|
|
query.then((res) => /* etc, etc */)
|
|
```
|
|
|
|
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` 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](https://github.com/brianc/node-pg-cursor) and [pg-query-stream](https://github.com/brianc/node-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`:
|
|
|
|
```js
|
|
const { Client, Query } = require('pg')
|
|
const query = client.query(new Query('SELECT NOW()'))
|
|
query.on('row', row => {})
|
|
query.on('end', res => {})
|
|
query.on('error', res => {})
|
|
```
|
|
|
|
`Query` is considered a public, documented part of the API of node-postgres and this form will be supported indefinitely.
|
|
|
|
_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](https://github.com/brianc/node-pg-cursor) or [pg-query-stream](https://github.com/brianc/node-pg-query-stream) and **not** the query object as an event emitter._
|