Cara membuat koneksi ke Postgres melalui Node.js

123

Saya menemukan diri saya mencoba membuat database postgres, jadi saya menginstal postgres dan memulai server dengan initdb /usr/local/pgsql/data, lalu saya memulai contoh itu dengan postgres -D /usr/local/pgsql/datasekarang bagaimana saya bisa berinteraksi dengan ini melalui node? Misalnya, apa jadinya connectionstring, atau bagaimana saya bisa mengetahui apa itu.

Doboy
sumber

Jawaban:

313

Berikut adalah contoh yang saya gunakan untuk menghubungkan node.js ke database Postgres saya.

Antarmuka di node.js yang saya gunakan dapat ditemukan di sini 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();
});

UPDATE: - query.onFungsinya sekarang sudah usang dan karenanya kode di atas tidak akan berfungsi sebagaimana mestinya. Sebagai solusi untuk tampilan ini di: - query.on bukanlah sebuah fungsi

Kuberchaun
sumber
24
Nah, itulah jenis contoh yang ingin saya lihat. Jelas dan termasuk kode yang cukup. Terima kasih JustBob.
Stradas
1
Apa yang Anda tambahkan di pg_hba.conf Anda untuk mengizinkan koneksi dari node.js? Terima kasih
Marius
3
host semua 0.0.0.0/0 md5 Entri ini akan jika saya ingat dengan benar membiarkan IP apapun terhubung. Ingatlah bahwa ini bukan khusus node, tetapi khusus PostgreSQL. Juga di postgresql.conf saya memiliki listen_addresses = '*'. Untuk pengaturan produksi, harap baca dokumennya untuk memastikan Anda tidak membuka lubang di mana pun. Saya menggunakan ini dalam pengaturan dev saya jadi saya baik-baik saja dalam mengizinkan mesin apa pun terhubung.
Kuberchaun
1
Parameter konString terbilang jenius, dan persis seperti yang saya cari. Terima kasih!
nelsonenzo
33

Pendekatan modern dan sederhana: 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]);

Lihat juga: Cara mendeklarasikan modul database Anda dengan benar .

vitaly-t
sumber
Meskipun tautan ini mungkin menjawab pertanyaan, lebih baik menyertakan bagian penting dari jawaban di sini dan menyediakan tautan untuk referensi. Jawaban link saja bisa menjadi tidak valid jika halaman tertaut berubah.
arulmr
1
Dalam dunia yang ideal - ya, namun, jawaban yang diterima di sini, seperti yang Anda lihat di atas - hanya tautannya saja. Sama seperti di sana, akan terlalu berlebihan untuk membuat abstrak dari informasi yang diberikan tautan, dan mengingat kedua tautan diberikan ke repositori publik GitHub, kemungkinan mereka mati tidak lebih dari peluang untuk StackOverflow mati .
vitaly-t
Mungkin hanya memberikan contoh sederhana tentang penggunaannya untuk sesuatu yang sangat mendasar, yang seharusnya hanya membutuhkan beberapa baris tetapi akan cukup untuk tidak menjadikannya hanya sebagai tautan.
Qantas 94 Heavy
@ Qantas94Heavy, dan saya baru saja melakukannya, tunda saat down-voting :)
vitaly-t
@ vitaly-t: Seseorang mungkin menandai posting sebagai "kualitas sangat rendah", yang memberikan downvote otomatis jika posting diedit atau dihapus sebelum bendera ditangani.
Qantas 94 Heavy
12

Hanya untuk menambahkan opsi yang berbeda - Saya menggunakan Node-DBI untuk terhubung ke PG, tetapi juga karena kemampuan untuk berbicara dengan MySQL dan sqlite. Node-DBI juga menyertakan fungsionalitas untuk membuat pernyataan pemilihan, yang berguna untuk melakukan hal-hal dinamis dengan cepat.

Sampel cepat (menggunakan informasi konfigurasi yang disimpan di file lain):

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
sumber
Hei, mlaccetti, saya memiliki masalah serupa saat mencoba menghubungkan dan menjalankan pengujian terhadap database SQLite3. Saya akan melalui tutorial dengan instruksi untuk menggunakan DBWrapper, itulah mengapa saya menghubungi Anda. Pertanyaan saya ada di sini: stackoverflow.com/q/35803874/1735836
Patricia
Node-DBI telah lama ditinggalkan, dan tidak lagi didukung.
vitaly-t
2

Salah satu solusi dapat menggunakan poolklien seperti berikut:

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

Anda dapat melihat detail lebih lanjut tentang sumber daya ini .

Oh Tuhan
sumber
Anda tidak menggunakan 'config'.
LEMUEL ADANE
1

Slonik adalah alternatif jawaban yang diajukan oleh Kuberchaun dan Vitaly.

Slonik menerapkan penanganan koneksi yang aman ; Anda membuat kumpulan koneksi dan pembukaan / penanganan koneksi ditangani untuk Anda.

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 adalah string koneksi Anda (atau secara lebih kanonis, URI atau DSN koneksi).

Manfaat dari pendekatan ini adalah bahwa skrip Anda memastikan bahwa Anda tidak pernah secara tidak sengaja meninggalkan koneksi yang menggantung.

Manfaat lain menggunakan Slonik meliputi:

Gajus
sumber
0

Kita juga bisa menggunakan postgresql-easy . Itu dibangun di atas node-postgres dan sqlutil . Catatan: pg_connection.js & your_handler.js ada di folder yang sama. db.js ada di folder config yang ditempatkan.

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

tangan_anda.js

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

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