如何通过 Node.js 连接 Postgres

我发现自己试图创建一个 postgres 数据库,所以我安装了 postgres 并用 initdb /usr/local/pgsql/data启动了一个服务器,然后用 postgres -D /usr/local/pgsql/data启动了那个实例,现在我如何通过节点与它交互?例如,什么是 connectionstring,或者我如何能够找出它是什么。

238886 次浏览

下面是我用来将 node.js 连接到 Postgres 数据库的一个示例。

我在 node.js 中使用的接口可以在这里找到 https://github.com/brianc/node-postgres

var pg = require('pg');
var conString = "postgres://YourUserName:YourPassword@localhost:5432/YourDatabase";


var client = new pg.Client(conString);
client.connect();


//queries are queued and executed one after another once the connection becomes available
var x = 1000;


while (x > 0) {
client.query("INSERT INTO junk(name, a_number) values('Ted',12)");
client.query("INSERT INTO junk(name, a_number) values($1, $2)", ['John', x]);
x = x - 1;
}


var query = client.query("SELECT * FROM junk");
//fired after last row is emitted


query.on('row', function(row) {
console.log(row);
});


query.on('end', function() {
client.end();
});






//queries can be executed either via text/parameter values passed as individual arguments
//or by passing an options object containing text, (optional) parameter values, and (optional) query name
client.query({
name: 'insert beatle',
text: "INSERT INTO beatles(name, height, birthday) values($1, $2, $3)",
values: ['George', 70, new Date(1946, 02, 14)]
});


//subsequent queries with the same name will be executed without re-parsing the query plan by postgres
client.query({
name: 'insert beatle',
values: ['Paul', 63, new Date(1945, 04, 03)]
});
var query = client.query("SELECT * FROM beatles WHERE name = $1", ['john']);


//can stream row results back 1 at a time
query.on('row', function(row) {
console.log(row);
console.log("Beatle name: %s", row.name); //Beatle name: John
console.log("Beatle birth year: %d", row.birthday.getYear()); //dates are returned as javascript dates
console.log("Beatle height: %d' %d\"", Math.floor(row.height / 12), row.height % 12); //integers are returned as javascript ints
});


//fired after last row is emitted
query.on('end', function() {
client.end();
});

更新:-query.on函数现在已经废弃,因此上面的代码将不能按预期工作。作为这方面的一个解决方案看:-On 不是函数

只是添加一个不同的选项-我使用 Node-DBI连接到 PG,但也由于能够与 MySQL 和 sqlite 交谈。Node-DBI 还包含构建 select 语句的功能,这对于动态处理动态内容非常方便。

快速示例(使用存储在另一个文件中的配置信息) :

var DBWrapper = require('node-dbi').DBWrapper;
var config = require('./config');


var dbConnectionConfig = { host:config.db.host, user:config.db.username, password:config.db.password, database:config.db.database };
var dbWrapper = new DBWrapper('pg', dbConnectionConfig);
dbWrapper.connect();
dbWrapper.fetchAll(sql_query, null, function (err, result) {
if (!err) {
console.log("Data came back from the DB.");
} else {
console.log("DB returned an error: %s", err);
}


dbWrapper.close(function (close_err) {
if (close_err) {
console.log("Error while disconnecting: %s", close_err);
}
});
});

Js:

var config = {
db:{
host:"plop",
database:"musicbrainz",
username:"musicbrainz",
password:"musicbrainz"
},
}
module.exports = config;

一种现代而简单的方法: 我保证:

const pgp = require('pg-promise')(/* initialization options */);


const cn = {
host: 'localhost', // server name or IP address;
port: 5432,
database: 'myDatabase',
user: 'myUser',
password: 'myPassword'
};


// alternative:
// var cn = 'postgres://username:password@host:port/database';


const db = pgp(cn); // database instance;


// select and return a single user name from id:
db.one('SELECT name FROM users WHERE id = $1', [123])
.then(user => {
console.log(user.name); // print user name;
})
.catch(error => {
console.log(error); // print the error;
});


// alternative - new ES7 syntax with 'await':
// await db.one('SELECT name FROM users WHERE id = $1', [123]);

参见: 如何正确声明数据库模块

一种解决方案是使用 pool客户端,如下所示:

const { Pool } = require('pg');
var config = {
user: 'foo',
database: 'my_db',
password: 'secret',
host: 'localhost',
port: 5432,
max: 10, // max number of clients in the pool
idleTimeoutMillis: 30000
};
const pool = new Pool(config);
pool.on('error', function (err, client) {
console.error('idle client error', err.message, err.stack);
});
pool.query('SELECT $1::int AS number', ['2'], function(err, res) {
if(err) {
return console.error('error running query', err);
}
console.log('number:', res.rows[0].number);
});

您可以在 这种资源上看到更多细节。

斯洛尼克是库伯查恩和维塔利提出的答案的替代者。

Slonik 实现了 安全连接操作安全连接操作; 您创建了一个连接池,连接打开/处理将为您处理。

import {
createPool,
sql
} from 'slonik';


const pool = createPool('postgres://user:password@host:port/database');


return pool.connect((connection) => {
// You are now connected to the database.
return connection.query(sql`SELECT foo()`);
})
.then(() => {
// You are no longer connected to the database.
});

postgres://user:password@host:port/database是您的连接字符串(或者更规范地说是连接 URI 或 DSN)。

这种方法的好处是,您的脚本可以确保您永远不会意外地离开挂起的连接。

使用 Slonik 的其他好处包括:

我们也可以使用 慢慢来。 它是建立在 Node-postgres(咒语)注意: Pg _ connect. js你的处理器在同一个文件夹中。 Db.js在放置的配置文件夹中。

Pg _ connect. js

const PgConnection = require('postgresql-easy');
const dbConfig = require('./config/db');
const pg = new PgConnection(dbConfig);
module.exports = pg;

./config/db.js

module.exports =  {
database: 'your db',
host: 'your host',
port: 'your port',
user: 'your user',
password: 'your pwd',
}

你的处理器

  const pg_conctn = require('./pg_connection');


pg_conctn.getAll('your table')
.then(res => {
doResponseHandlingstuff();
})
.catch(e => {
doErrorHandlingStuff()
})

连接字符串

连接字符串是表单的字符串:

postgres://[user[:password]@][host][:port][/dbname]

([...]中的部件可以选择包括或排除)

有效连接字符串的一些示例包括:

postgres://localhost
postgres://localhost:5432
postgres://localhost/mydb
postgres://user@localhost
postgres://user:secret_password@localhost

如果您刚刚在本地计算机上启动了一个数据库,连接字符串 postgres://localhost通常会正常工作,因为它使用默认端口号、用户名和没有密码。如果数据库是用特定的帐户启动的,您可能会发现需要使用 postgres://pg@localhostpostgres://postgres@localhost

如果这些都不起作用,并且您已经安装了 docker,那么另一种选择是运行 npx @databases/pg-test start。这将在一个 docker 容器中启动 postgres 服务器,然后为您打印连接字符串。pg-test数据库仅用于测试,因此如果计算机重新启动,您将丢失所有数据。

在 node.js 中连接

您可以使用 @databases/pg连接到数据库并发出查询:

const createPool = require('@databases/pg');
const {sql} = require('@databases/pg');


// If you're using TypeScript or Babel, you can swap
// the two `require` calls for this import statement:


// import createPool, {sql} from '@databases/pg';


// create a "pool" of connections, you can think of this as a single
// connection, the pool is just used behind the scenes to improve
// performance
const db = createPool('postgres://localhost');


// wrap code in an `async` function so we can use `await`
async function run() {


// we can run sql by tagging it as "sql" and then passing it to db.query
await db.query(sql`
CREATE TABLE IF NOT EXISTS beatles (
name TEXT NOT NULL,
height INT NOT NULL,
birthday DATE NOT NULL
);
`);


const beatle = {
name: 'George',
height: 70,
birthday: new Date(1946, 02, 14),
};


// If we need to pass values, we can use ${...} and they will
// be safely & securely escaped for us
await db.query(sql`
INSERT INTO beatles (name, height, birthday)
VALUES (${beatle.name}, ${beatle.height}, ${beatle.birthday});
`);


console.log(
await db.query(sql`SELECT * FROM beatles;`)
);
}


run().catch(ex => {
// It's a good idea to always report errors using
// `console.error` and set the process.exitCode if
// you're calling an async function at the top level
console.error(ex);
process.exitCode = 1;
}).then(() => {
// For this little demonstration, we'll dispose of the
// connection pool when we're done, so that the process
// exists. If you're building a web server/backend API
// you probably never need to call this.
return db.dispose();
});

您可以在 https://www.atdatabases.org/docs/pg上找到使用 node.js 查询 Postgres 的更完整的指南