Node Postgres 教程展示了如何使用带有 node-postgres 的 JavaScript 来处理 PostgreSQL 数据库。
node-postgres
node-postgres 是一组用于连接 PostgreSQL 数据库的 Node.js 模块。它支持回调、承诺、异步/等待、连接池、准备好的语句、游标和流式处理结果。
在我们的示例中,我们还使用了 Ramda 库。有关详细信息,请参阅 Ramda 教程。
设置节点postgres
首先,我们安装 node-postgres。
$ npm init -y
我们启动一个新的 Node 应用程序。
$ npm i pg
我们使用nmp i pg
安装 node-postgres。
$ npm i ramda
此外,我们安装 Ramda 以处理数据。
DROP TABLE IF EXISTS cars; CREATE TABLE cars(id SERIAL PRIMARY KEY, name VARCHAR(255), price INT); INSERT INTO cars(name, price) VALUES('Audi', 52642); INSERT INTO cars(name, price) VALUES('Mercedes', 57127); INSERT INTO cars(name, price) VALUES('Skoda', 9000); INSERT INTO cars(name, price) VALUES('Volvo', 29000); INSERT INTO cars(name, price) VALUES('Bentley', 350000); INSERT INTO cars(name, price) VALUES('Citroen', 21000); INSERT INTO cars(name, price) VALUES('Hummer', 41400); INSERT INTO cars(name, price) VALUES('Volkswagen', 21600);
在一些示例中,我们使用这个cars
表。
node-postgres 第一个例子
在第一个示例中,我们连接到 PostgreSQL 数据库并返回一个简单的 SELECT 查询结果。
const pg = require('pg'); const R = require('ramda'); const cs = 'postgres://postgres:s$cret@localhost:5432/ydb'; const client = new pg.Client(cs); client.connect(); client.query('SELECT 1 + 4').then(res => { const result = R.head(R.values(R.head(res.rows))); console.log(result); }).finally(() => client.end());
该示例连接到数据库并发出 SELECT 语句。
const pg = require('pg'); const R = require('ramda');
我们包括pg
和ramda
模块。
const cs = 'postgres://postgres:s$cret@localhost:5432/ydb';
这是 PostgreSQL 连接字符串。它用于建立与数据库的连接。
const client = new pg.Client(cs); client.connect();
一个客户端被创建。我们使用connect
连接到数据库。
client.query('SELECT 1 + 4').then(res => { const result = R.head(R.values(R.head(res.rows))); console.log(result); }).finally(() => client.end());
我们发出一个简单的 SELECT 查询。我们得到结果并将其输出到控制台。 res.rows
是一个对象数组;我们使用 Ramda 来获取返回的标量值。最后,我们用end
关闭连接。
$ node first.js 5
node-postgres 列名
在下面的示例中,我们获取数据库的列名。
const pg = require('pg'); const cs = 'postgres://postgres:s$cret@localhost:5432/ydb'; const client = new pg.Client(cs); client.connect(); client.query('SELECT * FROM cars').then(res => { const fields = res.fields.map(field => field.name); console.log(fields); }).catch(err => { console.log(err.stack); }).finally(() => { client.end() });
使用res.fields
属性检索列名。我们还使用 catch
子句来输出潜在的错误。
$ node column_names.js [ 'id', 'name', 'price' ]
输出显示cars
表的三个列名。
选择所有行
在下一个示例中,我们从数据库表中选择所有行。
const pg = require('pg'); const R = require('ramda'); const cs = 'postgres://postgres:s$cret@localhost:5432/ydb'; const client = new pg.Client(cs); client.connect(); client.query('SELECT * FROM cars').then(res => { const data = res.rows; console.log('all data'); data.forEach(row => { console.log(`Id: ${row.id} Name: ${row.name} Price: ${row.price}`); }) console.log('Sorted prices:'); const prices = R.pluck('price', R.sortBy(R.prop('price'), data)); console.log(prices); }).finally(() => { client.end() });
该示例输出 cars
表中的所有行和一个排序的汽车价格列表。
$ node all_rows.js all data Id: 1 Name: Audi Price: 52642 Id: 2 Name: Mercedes Price: 57127 Id: 3 Name: Skoda Price: 9000 Id: 4 Name: Volvo Price: 29000 Id: 5 Name: Bentley Price: 350000 Id: 6 Name: Citroen Price: 21000 Id: 7 Name: Hummer Price: 41400 Id: 8 Name: Volkswagen Price: 21600 Sorted prices: [ 9000, 21000, 21600, 29000, 41400, 52642, 57127, 350000 ]
node-postgres 参数化查询
参数化查询使用占位符而不是直接将值写入语句。参数化查询提高了安全性和性能。
const pg = require('pg'); const cs = 'postgres://postgres:s$cret@localhost:5432/ydb'; const client = new pg.Client(cs); client.connect(); const sql = 'SELECT * FROM cars WHERE price > $1'; const values = [50000]; client.query(sql, values).then(res => { const data = res.rows; data.forEach(row => console.log(row)); }).finally(() => { client.end() });
该示例在简单的 SELECT 语句中使用参数化查询。
const sql = 'SELECT * FROM cars WHERE price > $1';
这是 SELECT 查询。 $1
是一个占位符,稍后会以安全的方式替换为一个值。
const values = [50000];
这些是要插入到参数化查询中的值。
client.query(sql, values).then(res => {
这些值作为第二个参数传递给query
方法。
$ node parameterized.js { id: 1, name: 'Audi', price: 52642 } { id: 2, name: 'Mercedes', price: 57127 } { id: 5, name: 'Bentley', price: 350000 }
带有 async/await 的 node-postgres
Node Postgres 支持异步/等待语法。
const pg = require('pg'); const R = require('ramda'); const cs = 'postgres://postgres:s$cret@localhost:5432/ydb'; async function fetchNow() { const client = new pg.Client(cs); try { await client.connect(); let result = await client.query('SELECT now()'); return R.prop('now', R.head(result.rows)); } finally { client.end() } } fetchNow().then(now => console.log(now));
该示例使用 async/await 输出 SELECT now
查询的结果。
$ node async_await.js 2019-02-17T11:53:01.447Z
node-postgres 行模式
默认情况下,node-postgres 将数据作为对象数组返回。我们可以告诉 node-postgres 以数组的形式返回数据。
const pg = require('pg'); const R = require('ramda'); const cs = 'postgres://postgres:s$cret@localhost:5432/ydb'; const client = new pg.Client(cs); client.connect(); const query = { text: 'SELECT * FROM cars', rowMode: 'array' }; client.query(query).then(res => { const data = res.rows; console.log('all data'); data.forEach(row => { console.log(`Id: ${row[0]} Name: ${row[1]} Price: ${row[2]}`); }) console.log('Sorted prices:'); const prices = data.map(x => x[2]); const sorted = R.sort(R.comparator(R.lt), prices); console.log(sorted); }).finally(() => { client.end() });
该示例显示了cars
表中的所有行。它启用数组行模式。
const query = { text: 'SELECT * FROM cars', rowMode: 'array' };
我们使用将rowMode
设置为array
的配置对象。
console.log('all data'); data.forEach(row => { console.log(`Id: ${row[0]} Name: ${row[1]} Price: ${row[2]}`); })
现在我们遍历数组的数组。
$ node row_mode.js all data Id: 1 Name: Audi Price: 52642 Id: 2 Name: Mercedes Price: 57127 Id: 3 Name: Skoda Price: 9000 Id: 4 Name: Volvo Price: 29000 Id: 5 Name: Bentley Price: 350000 Id: 6 Name: Citroen Price: 21000 Id: 7 Name: Hummer Price: 41400 Id: 8 Name: Volkswagen Price: 21600 Sorted prices: [ 9000, 21000, 21600, 29000, 41400, 52642, 57127, 350000 ]
node-postgres 池示例
连接池提高了数据库应用程序的性能。它是特别有用的 Web 应用程序。
const pg = require('pg'); var config = { user: 'postgres', password: 's$cret', database: 'ydb' } const pool = new pg.Pool(config); pool.connect() .then(client => { return client.query('SELECT * FROM cars WHERE id = $1', [1]) .then(res => { client.release(); console.log(res.rows[0]); }) .catch(e => { client.release(); console.log(e.stack); }) }).finally(() => pool.end());
该示例显示了如何设置使用连接池的示例。完成查询后,我们调用 client.release
方法将连接返回到池中。
}).finally(() => pool.end());
pool.end
耗尽所有活动客户端的池,断开它们,并关闭池中的所有内部计时器。这在脚本中使用,例如本示例。在 Web 应用程序中,我们可以在 Web 服务器关闭时调用它,或者根本不调用它。
在本文中,我们使用node-postgres
在 Node.js 中与 PostgreSQL 交互。
列出所有 JavaScript 教程。