So stellen Sie über Node.js eine Verbindung zu Postgres her

123

Ich versuche gerade, eine Postgres-Datenbank zu erstellen, also habe ich Postgres installiert und einen Server mit initdb /usr/local/pgsql/datagestartet. Dann habe ich diese Instanz mit gestartet. postgres -D /usr/local/pgsql/dataWie kann ich mit dieser über den Knoten interagieren? Zum Beispiel, was wäre das connectionstringoder wie kann ich herausfinden, was es ist.

Doboy
quelle

Antworten:

313

Hier ist ein Beispiel, mit dem ich node.js mit meiner Postgres-Datenbank verbunden habe.

Die von mir verwendete Schnittstelle in node.js finden Sie hier 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: - Die query.onFunktion ist jetzt veraltet und daher funktioniert der obige Code nicht wie beabsichtigt. Als Lösung für diesen Blick auf: - query.on ist keine Funktion

Kuberchaun
quelle
24
Das ist die Art von Beispiel, die ich gerne sehe. Klar und inklusive gerade genug Code. Danke JustBob.
Stradas
1
Was haben Sie in Ihrer pg_hba.conf hinzugefügt, um Verbindungen von node.js zuzulassen? Danke
Marius
3
host all all 0.0.0.0/0 md5 Dieser Eintrag wird, wenn ich mich richtig erinnere, eine IP-Verbindung zulassen. Beachten Sie, dass dies nicht knotenspezifisch, sondern postgreSQL-spezifisch ist. Auch in postgresql.conf habe ich listen_addresses = '*'. Lesen Sie für Produktionseinstellungen die Dokumentation durch, um sicherzustellen, dass Sie nirgendwo Löcher öffnen. Ich verwende dies in meinem Entwickler-Setup, damit ich jedem Computer eine Verbindung erlauben kann.
Kuberchaun
1
Die angegebenen Parameter sind genial und genau das, wonach ich gesucht habe. Danke dir!
Nelsonenzo
33

Ein moderner und einfacher Ansatz: pg-versprechen :

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

Siehe auch: So deklarieren Sie Ihr Datenbankmodul korrekt .

vitaly-t
quelle
Während dieser Link die Frage beantworten kann, ist es besser, die wesentlichen Teile der Antwort hier aufzunehmen und den Link als Referenz bereitzustellen. Nur-Link-Antworten können ungültig werden, wenn sich die verknüpfte Seite ändert.
Arulmr
1
In einer idealen Welt - ja, und doch die akzeptierte Antwort hier, wie Sie oben sehen können - nur der Link auch. Wie dort wäre es einfach zu viel, aus den Informationen, die der Link enthält, eine Zusammenfassung zu erstellen. Angesichts der Tatsache, dass beide Links an die öffentlichen Repositorys von GitHub gesendet werden, ist die Wahrscheinlichkeit, dass sie tot sind, nicht höher als die Wahrscheinlichkeit, dass StackOverflow tot ist .
Vitaly-t
Vielleicht geben Sie nur ein einfaches Beispiel für die Verwendung für etwas sehr Grundlegendes, das nur ein paar Zeilen einnehmen sollte, aber ausreichen würde, um es nicht nur als Link zu verwenden.
Qantas 94 Heavy
@ Qantas94Heavy, und ich habe es gerade getan, halten Sie es bei der Abstimmung zurück :)
vitaly-t
@ vitaly-t: Jemand hat den Beitrag wahrscheinlich als "sehr schlechte Qualität" gekennzeichnet, was eine automatische Abwertung ergibt, wenn der Beitrag bearbeitet oder gelöscht wird, bevor die Flagge bearbeitet wird.
Qantas 94 Heavy
12

Nur um eine andere Option hinzuzufügen: Ich verwende Node-DBI , um eine Verbindung zu PG herzustellen, aber auch, weil ich mit MySQL und SQLite kommunizieren kann. Node-DBI enthält auch Funktionen zum Erstellen einer select-Anweisung, die praktisch ist, um dynamische Aufgaben im laufenden Betrieb auszuführen.

Kurzbeispiel (unter Verwendung von Konfigurationsinformationen, die in einer anderen Datei gespeichert sind):

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
quelle
Hey, mlaccetti, ich habe ein ähnliches Problem beim Versuch, eine Verbindung herzustellen und Tests für eine SQLite3-Datenbank auszuführen. Ich gehe ein Tutorial mit Anweisungen zur Verwendung von DBWrapper durch, weshalb ich mich an Sie wende. Meine Frage ist hier: stackoverflow.com/q/35803874/1735836
Patricia
Node-DBI wurde seitdem lange aufgegeben und nicht mehr unterstützt.
Vitaly-t
2

Eine Lösung kann die Verwendung poolvon Clients wie den folgenden sein:

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

Sie können weitere Details zu dieser Ressource sehen .

Oh mein Gott
quelle
Sie haben 'config' nicht verwendet.
LEMUEL ADANE
1

Slonik ist eine Alternative zu den von Kuberchaun und Vitaly vorgeschlagenen Antworten.

Slonik implementiert eine sichere Verbindungshandhabung . Sie erstellen einen Verbindungspool und die Verbindungsöffnung / -behandlung wird für Sie erledigt.

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 ist Ihre Verbindungszeichenfolge (oder kanonischer eine Verbindungs-URI oder ein DSN).

Der Vorteil dieses Ansatzes besteht darin, dass Ihr Skript sicherstellt, dass Sie niemals versehentlich hängende Verbindungen verlassen.

Weitere Vorteile für die Verwendung von Slonik sind:

Gajus
quelle
0

Wir können auch postgresql-easy verwenden . Es basiert auf Node-Postgres und Sqlutil . Hinweis: pg_connection.js und your_handler.js befinden sich im selben Ordner. db.js befindet sich im Konfigurationsordner.

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()     
      })
Naveen Karnam
quelle