নোড.জেএস পোস্টগ্রেসকিএল মডিউলটি ব্যবহার করার সঠিক উপায় কী?


95

আমি হিরোকুতে একটি নোড.জেএস অ্যাপ লিখছি এবং পিজি মডিউলটি ব্যবহার করছি । প্রতিটি অনুরোধের জন্য আমাকে যে ডাটাবেসটি জিজ্ঞাসা করতে হবে তার জন্য "সঠিক" উপায়টি আমি বের করতে পারি না।

ডকুমেন্টেশনে এই জাতীয় কোড ব্যবহার করা হয়:

pg.connect(conString, function(err, client) {
  // Use the client to do things here
});

তবে অবশ্যই আপনাকে pg.connectডাটাবেসটি সঠিকভাবে ব্যবহার করে এমন প্রতিটি ফাংশনের ভিতরে কল করার দরকার নেই? আমি অন্যান্য কোড দেখেছি যা এটি করে:

var conString = process.env.DATABASE_URL || "tcp://postgres:1234@localhost/postgres";
var client = new pg.Client(conString);
client.connect();
// client is a global so you can use it anywhere now

আমি দ্বিতীয় বিকল্পের দিকে ঝুঁকছি যেহেতু আমি বিশ্বাস করি যে হিরোকুর জন্য নিখরচায় ডেটাবেস উদাহরণ কোনওভাবেই একটি সংযোগের মধ্যে সীমাবদ্ধ তবে এইভাবে এটি করার ক্ষেত্রে কোনও অসুবিধা আছে কি? আমার ক্লায়েন্ট অবজেক্টটি আমি ব্যবহার করার আগে প্রতিবার এখনও সংযুক্ত আছে কিনা তা কি আমাকে খতিয়ে দেখার দরকার আছে?

উত্তর:


158

আমি নোড-পোস্টগ্রেসের লেখক । প্রথমত, আমি ক্ষমা চেয়েছি ডকুমেন্টেশন সঠিক বিকল্পটি পরিষ্কার করতে ব্যর্থ হয়েছে: এটি আমার দোষ। আমি এটি উন্নত করার চেষ্টা করব। এটি ব্যাখ্যা করার জন্য আমি ঠিক এখনই একটি গিস্ট লিখেছি কারণ টুইটারের জন্য কথোপকথনটি অনেক দীর্ঘ হয়েছে।

ওয়েব পরিবেশে যাওয়ার উপায়টি ব্যবহার pg.connectকরা ।

পোস্টগ্রিএসকিউএল সার্ভার সংযোগ প্রতি একযোগে কেবলমাত্র 1 টি ক্যোয়ারিকে পরিচালনা করতে পারে। এর অর্থ যদি new pg.Client()আপনার ব্যাকএন্ডের সাথে যদি 1 টি বিশ্বব্যাপী সংযুক্ত থাকে তবে দ্রুত পোস্টগ্রাইস কীভাবে প্রশ্নের জবাব দিতে পারে তার উপর ভিত্তি করে আপনার পুরো অ্যাপ্লিকেশনটি বোতলজাত রয়েছে। এটি প্রতিটি কোয়েরিকে সারিবদ্ধভাবে আক্ষরিকভাবে সমস্ত কিছু সীমাবদ্ধ করবে। হ্যাঁ, এটি async এবং তাই ঠিক আছে ... তবে আপনি বরং নিজের থ্রুটপুটকে 10x দিয়ে গুণাবেন না? বুদ্ধিমান কিছুতে pg.connect সেটটি ব্যবহার করুন pg.defaults.poolSize(আমরা 25-100 করি, সঠিক নম্বরটি এখনও নিশ্চিত নই)।

new pg.Clientযখন আপনি জানেন আপনি কি করছেন for যখন কোনও কারণে আপনার দীর্ঘকালীন ক্লায়েন্টের প্রয়োজন হয় বা খুব সাবধানে জীবনচক্রটি নিয়ন্ত্রণ করতে হয়। এর ভাল উদাহরণ হ'ল ব্যবহার করার সময় LISTEN/NOTIFY। শ্রোতা ক্লায়েন্টের চারপাশে থাকা এবং সংযুক্ত হওয়া এবং ভাগ করার দরকার নেই যাতে এটি NOTIFYবার্তাগুলি সঠিকভাবে পরিচালনা করতে পারে । অন্য উদাহরণটি হ'ল কিছু হ্যাং স্টাফ বা কমান্ড লাইন স্ক্রিপ্টগুলিতে মারার জন্য 1-অফ ক্লায়েন্ট খোলার সময়।

একটি খুব সহায়ক জিনিস হ'ল আপনার অ্যাপ্লিকেশনটিতে আপনার ডাটাবেসে সমস্ত ফাইল অ্যাক্সেসকে একটি ফাইলে কেন্দ্রিয় করে তোলা। কোনও জায়গায় লিটার pg.connectকল বা নতুন ক্লায়েন্ট করবেন না । এর মতো একটি ফাইল db.jsদেখায়:

module.exports = {
   query: function(text, values, cb) {
      pg.connect(function(err, client, done) {
        client.query(text, values, function(err, result) {
          done();
          cb(err, result);
        })
      });
   }
}

এইভাবে আপনি নিজের প্রয়োগটি pg.connectক্লায়েন্টের কাস্টম পুলে বা যে কোনও কিছুতে পরিবর্তন করতে পারবেন এবং কেবল কোনও জায়গায় জিনিসগুলি পরিবর্তন করতে হবে।

কটাক্ষপাত আছে নোড-PG-ক্যোয়ারী মডিউল যে শুধু এই আছে।


4
দুঃখিত, আমি ডিবিএমএসে মোটামুটি নতুন এবং আমার এখনও এটি বুঝতে সমস্যা হয় তবে আমরা কেন "লিটার pg.connect" কল করতে চাই না? এটি কি সরলতার জন্য বা পারফরম্যান্সের কারণে? উদাহরণস্বরূপ, আমি আমার বেসিক অ্যাপ্লিকেশনটিতে (প্রতিটি একই কনস্ট্রস্ট্রিং সহ) প্রতিটি রুটে একবার pg.connect কল করি। এটা ঠিক আছে? স্বজ্ঞাতভাবে, এটি মনে হয় যে এটি যখনই আমি কল করি (যা আমি চাই না) একই ডিবিতে একটি নতুন সংযোগ তৈরি করছে, তবে কী এটি পুলযুক্ত সংযোগগুলি অভ্যন্তরীণভাবে ব্যবহার করে? ধন্যবাদ
ব্যবহারকারী 1164937

অসাধারণ. আপনি কেন প্রতি অনুরোধের পরিবর্তে ক্যোয়ারী অনুসারে একটি সংযোগ নিযুক্ত করছেন? আমি একটি অনুরোধের মধ্যে একাধিক প্রশ্নের জুড়ে একটি সংযোগ ভাগ করার জন্য একটি উপযুক্ত উপায় সন্ধান করছি এবং আপনার উত্তরটি এখানে সন্ধানের আগে রেজোল্স লোকাল বিবেচনা করেছি।
জো ল্যাপ

4
অপেক্ষা কর. দেখে মনে হচ্ছে আপনার সমাধান এখানে লেনদেন সমর্থন করবে না।
জো ল্যাপ

4
পিজি সংযোগ কীভাবে বন্ধ করবেন?
বর্ধন

4
নোট-পোস্টগ্রাস ওরফে পিজি-র পোস্ট v7 অপসারণ করা হয়েছে তা নোট করুন। স্ট্যাকওভারফ্লো
কলিন ডি

24

আমি পিজি-প্রতিশ্রুতির লেখক , যা প্রতিশ্রুতির মাধ্যমে নোড-পোস্টগ্রিজের ব্যবহারকে সহজ করে তোলে

এটি স্বয়ংক্রিয় লেনদেনের মতো নোড-পোস্টগ্র্রেস দ্বারা প্রয়োগ করা সংযোগ পুলটি ব্যবহার করে ডাটাবেস থেকে সংযোগ ও সংযোগ বিচ্ছিন্ন করার সঠিক উপায় সম্পর্কিত বিষয়গুলিকে সম্বোধন করে ।

পিজি-প্রতিশ্রুতিতে স্বতন্ত্র অনুরোধটি কেবল আপনার ব্যবসায়িক যুক্তির সাথে প্রাসঙ্গিকভাবে এটিকে ফুটিয়ে তোলে:

db.any('SELECT * FROM users WHERE status = $1', ['active'])
    .then(data => {
        console.log('DATA:', data);
    })
    .catch(error => {
        console.log('ERROR:', error);
    });

অর্থাত্ ক্যোয়ারিগুলি সম্পাদন করার সময় আপনার সংযোগ যুক্তির সাথে মোকাবিলা করার দরকার নেই, কারণ আপনি সংযোগটি কেবল একবার বিশ্বব্যাপী সেট আপ করেছেন:

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

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

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

আপনি উদাহরণ টিউটোরিয়াল শিখুন বা প্রকল্পের হোম পৃষ্ঠায় আরও অনেক উদাহরণ খুঁজে পেতে পারেন ।


হাই, হেরোকু কেবলমাত্র এসএসএল সংযোগগুলি গ্রহণ করে। এটি pgদ্বারা নির্দিষ্ট করা হয় pg.defaults.ssl = true;। আপনি এটি কিভাবে করবেন pg-promise?
অক্টোবর

@ocram github.com/vitaly-t/pg-promise/wiki/… , অথবা আপনি সংযোগের প্যারামিটারের মধ্যে এসএসএল উল্লেখ করতে পারেন: github.com/vitaly-t/pg-promise/wiki/Connication- সিন্ট্যাক্স
প্রাণশক্তি-টি

আমি এর বেশিরভাগ ক্ষেত্রেই আমি নতুন: জাভাস্ক্রিপ্ট, প্রতিশ্রুতি, পোস্টগ্রিজ ইত্যাদি and এবং এটি আমার প্রয়োজন ঠিক তাই। ধন্যবাদ!!
রায়ান রোডমায়ার

4
@ ক্র্যাম আমি সবেমাত্র এই কাজটি করে পেয়েছিpgp.pg.defaults.ssl = true;
চার্লিসি

আমরা পোস্টগ্রিজকে একাধিক কোয়েরি অনুরোধ দিলে কি স্বয়ংক্রিয়ভাবে পোস্টগ্রিজ থ্রুপুট উন্নত করতে একাধিক সংযোগ তৈরি করবে?
সুন্দরের

5

পুলটি এখন যাবার উপায়

const { Pool } = require('pg');

    const pool = new Pool({
      connectionString: DATABASE_URL,
      ssl: false,
      max: 20,
      idleTimeoutMillis: 30000,
      connectionTimeoutMillis: 2000,
    });
    module.exports = {
        query: (text, params) => pool.query(text, params)
      }

এটি হিসাবে ব্যবহার করা যেতে পারে db.query('<BEGIN,COMMIT,ROLLBACK,your query,anything')


1

বিশ্বব্যাপী একটি পিজি পুল তৈরি করা ভাল এবং প্রতিবার আপনার যখন ডিবি অপারেশন করতে হবে তখন ক্লায়েন্টটি ব্যবহার করুন এবং তারপরে এটি পুনরায় ছেড়ে দিন। সমস্ত ডিবি অপারেশন হয়ে গেলে পুলটি ব্যবহার করে শেষ করুনpool.end()

কোডের উদাহরণ -

let pool = new pg.Pool(dbConfig);
pool.connect(function(err, client, done) {

if (err) {
    console.error('Error connecting to pg server' + err.stack);
    callback(err);
} else {
    console.log('Connection established with pg db server');

    client.query("select * from employee", (err, res) => {

            if (err) {
                console.error('Error executing query on pg db' + err.stack);
                callback(err);
            } else {
                console.log('Got query results : ' + res.rows.length);


               async.each(res.rows, function(empRecord) {   
                        console.log(empRecord.name);
                });
            }
            client.release();

        });
}

});  

আরও তথ্যের জন্য, আপনি আমার ব্লগ পোস্ট - উত্স পড়তে পারেন


0

আপনি ডকুমেন্টেশন থেকে দেখতে পাচ্ছেন যে উভয় বিকল্পই বৈধ, সুতরাং আপনি যেটি পছন্দ করেন তা চয়ন করুন। আপনি হিসাবে, আমি দ্বিতীয় পছন্দ সঙ্গে যেতে হবে।


সংযোগটি ড্রপ হয়ে গেলে পুনরায় সংযোগ সম্পর্কে কী বলা যায়? তা কি স্বয়ংক্রিয়ভাবে সম্পন্ন হয়? ত্রুটি পরিচালনা করার উইকি পৃষ্ঠাটি হ'ল ... খালি github.com/brianc/node-postgres/wiki/Error-handling
alltom

: আমি এটা আলাদাভাবে জিজ্ঞাসা করেছি stackoverflow.com/questions/15619456/...
alltom

-1

আমি এটির জন্য খুব সাধারণ হ্যান্ডলারের প্রতি আগ্রহী তাই আমি এটিকে জটিল না করে নিজের তৈরি করেছি। আমি কোনও বিভ্রমের মধ্যে নেই যে এটি অত্যন্ত মৌলিক তবে এটি কিছু লোককে শুরু করতে সহায়তা করতে পারে। মূলত, এটি সংযোগ স্থাপন করে, অনুসন্ধানগুলি চালায় এবং আপনার জন্য ত্রুটিগুলি পরিচালনা করে।

function runQuery(queryString, callback) {
  // connect to postgres database
  pg.connect(postgresDatabase.url,function(err,client,done) {
    // if error, stop here
    if (err) {console.error(err); done(); callback(); return;}
    // execute queryString
    client.query(queryString,function(err,result) {
      // if error, stop here
      if (err) {console.error(err+'\nQuery: '+queryString); done(); callback(); return;}
      // callback to close connection
      done();
      // callback with results
      callback(result.rows);
    });
  });
}

তারপরে আপনি এটিকে কল করে ব্যবহার করবেন:

runQuery("SELECT * FROM table", function(result) {
  // Whatever you need to do with 'result'
}

এটি এমনকি পুলটিতে সংযোগটি ছেড়ে দেয় না। এটি পুলটি বাস্তবের দ্রুত দ্রুত হ্রাস করবে। node-postgresপৃষ্ঠায় মূল উদাহরণটি এর চেয়ে ভাল করে।
প্রাণবন্ত- t

-2

এখানে আমি এটি কীভাবে করব তা "উপরের সমস্ত পদ্ধতির" বাছাই করুন

Promise = require 'bluebird'
pg = module.exports = require 'pg'

Promise.promisifyAll pg.Client.prototype
Promise.promisifyAll pg.Client
Promise.promisifyAll pg.Connection.prototype
Promise.promisifyAll pg.Connection
Promise.promisifyAll pg.Query.prototype
Promise.promisifyAll pg.Query
Promise.promisifyAll pg

connectionString = process.env.DATABASE_URL

module.exports.queryAsync = (sql, values) ->
  pg.connectAsync connectionString
  .spread (connection, release) ->
    connection.queryAsync sql, values
    .then (result) ->
      console.log result.rows[0]
    .finally ->
      release()

4
সুতরাং আপনি কোনও সংযোগ ব্যবস্থাপনার, কোনও লেনদেন সমর্থন এবং কোনও কার্য সমর্থন নয় with তাহলে কি কথা?
প্রাণবন্ত- t

4
ঐটা কি ভাষা? কফি? Berk
caub
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.