วิธีเชื่อมต่อกับ Postgres ผ่าน Node.js


123

ฉันพบว่าตัวเองกำลังพยายามสร้างฐานข้อมูล postgres ดังนั้นฉันจึงติดตั้ง postgres และเริ่มเซิร์ฟเวอร์ด้วยinitdb /usr/local/pgsql/dataจากนั้นฉันก็เริ่มอินสแตนซ์นั้นโดยpostgres -D /usr/local/pgsql/dataตอนนี้ฉันจะโต้ตอบกับสิ่งนี้ผ่านโหนดได้อย่างไร ตัวอย่างเช่นจะconnectionstringเป็นอย่างไรหรือฉันจะรู้ได้อย่างไรว่ามันคืออะไร

คำตอบ:


313

นี่คือตัวอย่างที่ฉันใช้ในการเชื่อมต่อ 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ฟังก์ชันนี้เลิกใช้งานแล้วดังนั้นโค้ดด้านบนจึงไม่ทำงานตามที่ตั้งใจไว้ เป็นวิธีแก้ปัญหาสำหรับรูปลักษณ์นี้: - query.on ไม่ใช่ฟังก์ชัน


24
ตอนนี้เป็นตัวอย่างที่ฉันชอบดู ชัดเจนและรวมรหัสเพียงพอ ขอบคุณ JustBob
Stradas

1
คุณเพิ่มอะไรใน pg_hba.conf เพื่ออนุญาตการเชื่อมต่อจาก node.js ขอบคุณ
Marius

3
โฮสต์ทั้งหมด 0.0.0.0/0 md5 รายการนี้ถ้าฉันจำไม่ผิดให้เชื่อมต่อ IP ใด ๆ โปรดทราบว่านี่ไม่ใช่โหนดเฉพาะ แต่เฉพาะ PostgreSQL นอกจากนี้ใน postgresql.conf ฉันมี listen_addresses = '*' สำหรับการตั้งค่าการผลิตโปรดอ่านเอกสารเพื่อให้แน่ใจว่าคุณไม่ได้เปิดช่องใด ๆ ฉันใช้สิ่งนี้ในการตั้งค่า dev ดังนั้นฉันจึงสามารถอนุญาตให้เชื่อมต่อกับเครื่องใดก็ได้
Kuberchaun

1
พารามิเตอร์ conString ที่สะกดออกมานั้นเป็นอัจฉริยะและเป็นสิ่งที่ฉันกำลังมองหา ขอบคุณ!
เนลสันเซนโซ


33

แนวทางที่ทันสมัยและเรียบง่าย: pg-Promise :

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]);

ดูเพิ่มเติม: วิธีการประกาศโมดูลฐานข้อมูลของคุณอย่างถูกต้องวิธีการอย่างถูกต้องประกาศโมดูลฐานข้อมูลของคุณ


แม้ว่าลิงก์นี้อาจตอบคำถามได้ แต่ควรรวมส่วนสำคัญของคำตอบไว้ที่นี่และระบุลิงก์เพื่อการอ้างอิง คำตอบแบบลิงก์เท่านั้นอาจไม่ถูกต้องหากหน้าที่เชื่อมโยงเปลี่ยนไป
arulmr

1
ในโลกแห่งอุดมคติ - ใช่ แต่คำตอบที่ได้รับการยอมรับที่นี่ดังที่คุณเห็นด้านบน - เพียงแค่ลิงค์ด้วย เช่นเดียวกับที่นั่นมันจะมากเกินไปที่จะสร้างบทคัดย่อจากข้อมูลที่ลิงค์ให้และเมื่อพิจารณาว่าลิงก์ทั้งสองถูกส่งไปยังที่เก็บสาธารณะของ GitHub โอกาสที่พวกเขาจะตายนั้นไม่เกินโอกาสที่ StackOverflow จะตาย .
vitaly-t

อาจจะแค่ยกตัวอย่างง่ายๆของการใช้มันสำหรับบางสิ่งที่พื้นฐานมากซึ่งควรใช้เวลาเพียงไม่กี่บรรทัด แต่ก็เพียงพอแล้วที่จะไม่ทำให้เป็นลิงค์เท่านั้น
Qantas 94 Heavy

@ Qantas94Heavy, และฉันก็ทำ, หยุดมันลง - โหวต :)
vitaly-t

@ vitaly-t: อาจมีคนตั้งค่าสถานะโพสต์ว่า "คุณภาพต่ำมาก" ซึ่งจะให้การโหวตลงโดยอัตโนมัติหากโพสต์ได้รับการแก้ไขหรือลบก่อนที่จะมีการตั้งค่าสถานะ
Qantas 94 Heavy

12

เพียงเพื่อเพิ่มตัวเลือกอื่น - ฉันใช้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);
    }
  });
});

config.js:

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

สวัสดี mlaccetti ฉันมีปัญหาที่คล้ายกันในการพยายามเชื่อมต่อและเรียกใช้การทดสอบกับฐานข้อมูล SQLite3 ฉันกำลังอ่านบทช่วยสอนพร้อมคำแนะนำในการใช้ DBWrapper ซึ่งเป็นเหตุผลว่าทำไมฉันจึงติดต่อคุณ คำถามของฉันอยู่ที่นี่: stackoverflow.com/q/35803874/1735836
Patricia

Node-DBI ถูกละทิ้งไปนานแล้วและไม่ได้รับการสนับสนุนอีกต่อไป
vitaly-t

3

โซลูชันหนึ่งที่สามารถใช้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);
});

คุณสามารถดูรายละเอียดเพิ่มเติมเกี่ยวกับทรัพยากรนี้นี้


คุณไม่ได้ใช้ 'config'
LEMUEL ADANE

1

Slonikเป็นอีกทางเลือกหนึ่งสำหรับคำตอบที่เสนอโดย Kuberchaun และ Vitaly

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 ได้แก่ :


0

นอกจากนี้เรายังสามารถใช้PostgreSQL ง่าย มันถูกสร้างขึ้นบนโหนด postgresและsqlutil หมายเหตุ: pg_connection.js & your_handler.jsอยู่ในโฟลเดอร์เดียวกัน db.jsอยู่ในโฟลเดอร์ config ที่วางไว้

pg_connection.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',
}

your_handler.js

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

  pg_conctn.getAll('your table')
    .then(res => {
         doResponseHandlingstuff();
      })
    .catch(e => {
         doErrorHandlingStuff()     
      })
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.