web-dev-qa-db-ja.com

node.js mysqlプール接続とasync / await

_async/ await_構文でmysqljs/mysql libから取得したpool.getConnection()を使用する方法はありますか?

アイデアは、それを解放する前に、さまざまな外部キー制約(順次クエリ)を持つ書き込みクエリ間で渡される1つの接続を返すと同時に、さまざまな読み取りクエリの目的でプールからさらに接続を取得するメソッドを持つことです。 (平行)。

6
Schmalitz

私の実際の例を共有してください:

私はこれを使用します Node.js用の約束されたMySQLミドルウェア

この記事を読む Node.js 8とAsync/Awaitを使用してMySQLデータベースミドルウェアを作成する

これが私のdatabase.jsです

var mysql = require('mysql'); 

// node -v must > 8.x 
var util = require('util');


//  !!!!! for node version < 8.x only  !!!!!
// npm install util.promisify
//require('util.promisify').shim();
// -v < 8.x  has problem with async await so upgrade -v to v9.6.1 for this to work. 



// connection pool https://github.com/mysqljs/mysql   [1]
var pool = mysql.createPool({
  connectionLimit : process.env.mysql_connection_pool_Limit, // default:10
  Host     : process.env.mysql_Host,
  user     : process.env.mysql_user,
  password : process.env.mysql_password,
  database : process.env.mysql_database
})


// Ping database to check for common exception errors.
pool.getConnection((err, connection) => {
if (err) {
    if (err.code === 'PROTOCOL_CONNECTION_LOST') {
        console.error('Database connection was closed.')
    }
    if (err.code === 'ER_CON_COUNT_ERROR') {
        console.error('Database has too many connections.')
    }
    if (err.code === 'ECONNREFUSED') {
        console.error('Database connection was refused.')
    }
}

if (connection) connection.release()

 return
 })

// Promisify for Node.js async/await.
 pool.query = util.promisify(pool.query)



 module.exports = pool

ノード-v> 8.xをアップグレードする必要があります

awaitを使用するには、非同期関数を使用する必要があります。

例:

   var pool = require('./database')

  // node -v must > 8.x, --> async / await  
  router.get('/:template', async function(req, res, next) 
  {
      ...
    try {
         var _sql_rest_url = 'SELECT * FROM arcgis_viewer.rest_url WHERE id='+ _url_id;
         var rows = await pool.query(_sql_rest_url)

         _url  = rows[0].rest_url // first record, property name is 'rest_url'
         if (_center_lat   == null) {_center_lat = rows[0].center_lat  }
         if (_center_long  == null) {_center_long= rows[0].center_long }
         if (_center_zoom  == null) {_center_zoom= rows[0].center_zoom }          
         _place = rows[0].place


       } catch(err) {
                        throw new Error(err)
       }
9
hoogw

仲間。理由はわかりませんが、1日中試しましたが、うまくいきませんでした。あなたのコメントの助けを借りて、私はもう一度試しましたが、もちろんそれはうまくいきます。

db.js:

const pool = mysql.createPool(config);

exports.getConnection = () => {
    return new Promise((resolve, reject) => {
        pool.getConnection(function (err, connection) {
            if (err) {
                return reject(err);
            }
            resolve(connection);
        });
    });
};

someWhereElse.js:

const db = require('./db');

const wrappingFunction = async () => {
    const connection = await db.getConnection();
    console.log(connection);
};
wrappingFunction();
3
Schmalitz

以前の回答(til.promisifyを使用)は機能しませんでした。Promiseを手動で実装するだけで機能します。

関数:

async function removeItem (id)  {

return new Promise( (resolve) => {
    pool.query('DELETE FROM table_name WHERE id=' + id, (error) => {
          resolve ({result: !error});
        });
    }); 
} 

使用法:

const app = express();
const mysql = require('mysql');
const pool = mysql.createPool({
            connectionLimit: 10,
            Host: 'localhost',
            user: 'login',
            password: 'pass',
            database: 'dbname'
        });



app.post("/:id", async (req, res) => {
        const answer = await itemRemove(id);
        res.send(answer);
    });
1
ILya Kravchenko

手動でpromiseを実装する方がよいオプションのようです。コードで使用したものを共有する-

const mysql = require('mysql');
const config = require('config');

const pool = mysql.createPool(config.get('db.mysql'));

module.exports = {
    checkConnection: () => {
        return new Promise((resolve, reject) => {
            pool.getConnection((err, conn) => {
                if (err) {
                    return reject(err);
                }
                resolve(conn.release());
            });
        });
    },
    pool,
    closeConnection: () => pool.end(),
};
1
realnikunj

確かに、最初にそれを約束する必要があります。これはnode 8.0.0以降に実行できます。

const util = require('util');

async function doSomething() {
     const getConnectionAsync = util.promisify(pool.getConnection);
   try {
       const result = await getConnectionAsync('MASTER');
    }catch(err) {
       console.log('Oh no');
    }
} 

何らかの理由でノード8以上を使用できない場合、 http://bluebirdjs.com/docs/api/promise.promisify.html のように、ノード8を約束する他の方法があります。

0

私がいつもコードで使用しているものを共有するだけです:

//Filename: MySQL.js    

module.exports = {
    connect: function ()
    {
        return new Promise((resolve, reject) => {

        let pool = Mysql.createPool({ //require configfile.js or just put connection detail here
                connectionLimit: config.mysql.connectionLimit,
                Host: config.mysql.Host,
                user: config.mysql.user,
                password: config.mysql.password,
                database: config.mysql.database
            });

            pool.getConnection((err, connection) =>
            {
                try
                {
                    if (connection)
                    {
                        resolve({"status":"success", "data":"MySQL connected.", "con":pool});
                        connection.release();
                    }
                }
                catch (err)
                {
                    reject({"status":"failed", "error":`MySQL error. ${err}`});
                }
                resolve({"status":"failed", "error":"Error connecting to MySQL."});
            });
        });
    }
}

その後、MySQLへの接続を呼び出す必要があるときはいつでも

//Filename: somefile.js

const useMySQL = require('./path/to/MySQL');

module.exports = {

    getSomething: function () {
        return new Promise(async (resolve) => {

            try
            {
                let connection = await useMySQL.connect();
                con = connection.con;

                //Do some query here, then
                resolve(`Send some result/handle error`);
            }
            catch (err)
            {
                //Handle error if any, log, etc, and eventually
                resolve(err);

            }
        });
    }

お役に立てれば。

0
razu