web-dev-qa-db-fra.com

connexion au pool mysql node.js avec async / wait

Existe-t-il un moyen d'utiliser pool.getConnection() tirée de la bibliothèque mysqljs/mysql avec la async/ await syntaxe?

L'idée est d'avoir une méthode qui retourne une connexion qui peut être transmise entre les requêtes d'écriture avec diverses contraintes de clé étrangère (requêtes séquentielles) avant de la libérer et en même temps potentiellement obtenir d'autres connexions du pool pour diverses requêtes de lecture (parallèle).

6
Schmalitz

Partagez mon exemple de travail:

J'utilise ceci middleware MySQL promis pour Node.js

lire cet article Créer un middleware de base de données MySQL avec Node.js 8 et Async/Await

voici ma base de données.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

Vous devez mettre à niveau le nœud -v> 8.x

vous devez utiliser la fonction asynchrone pour pouvoir utiliser l'attente.

exemple:

   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

Compagnons. Je ne sais pas pourquoi mais j'ai essayé toute la journée mais je n'ai pas réussi à le faire fonctionner. À l'aide de vos commentaires, j'ai réessayé et cela fonctionne bien sûr.

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

Les réponses précédentes (avec til.promisify) ne fonctionnaient pas pour moi, et l'implémentation manuelle de Promise ne fonctionne que:

Fonction:

async function removeItem (id)  {

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

Usage:

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

Il semble que la mise en œuvre manuelle des promesses soit une meilleure option. Je partage juste ce que j'ai utilisé dans mon code -

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

Bien sûr, vous devez d'abord le promettre, ce que vous pouvez faire depuis node 8.0.0 maintenant:

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

Si, pour une raison quelconque, vous ne pouvez pas utiliser le nœud 8 ou supérieur, il existe d'autres façons de le promettre, comme http://bluebirdjs.com/docs/api/promise.promisify.html

0
Daniel Conde Marin

Je partage juste ce que j'ai toujours utilisé dans mon code:

//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."});
            });
        });
    }
}

Ensuite, chaque fois que vous devez appeler la connexion à 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);

            }
        });
    }

J'espère que cela t'aides.

0
razu