【问题标题】:Node.js - PostgreSQL (pg) : Client has already been connected. You cannot reuse a clientNode.js - PostgreSQL (pg):客户端已经连接。您不能重用客户端
【发布时间】:2020-11-14 09:11:58
【问题描述】:

我只是想写一个简单的注册/登录系统。 我正在尝试查找用户名是否存在。步骤如下:

  1. 转到 localhost:3000/users/register 页面
  2. 填写所有字段并点击注册按钮
  3. 检查我的命令行是否存在用户名,它应该使用 console.log 打印它

到目前为止一切正常。

当我返回注册页面时,我再次填写所有字段并单击注册按钮。然后它在命令行中抛出它:

Error: Client has already been connected. You cannot reuse a client.
at Client._connect (C:\Users\Hasan\Desktop\Projeler\node-ogreniyorum\node_modules\pg\lib\client.js:91:17)
at C:\Users\Hasan\Desktop\Projeler\node-ogreniyorum\node_modules\pg\lib\client.js:310:10
at new Promise (<anonymous>)
at Client.connect (C:\Users\Hasan\Desktop\Projeler\node-ogreniyorum\node_modules\pg\lib\client.js:309:10)
at Object.module.exports.findUserById (C:\Users\Hasan\Desktop\Projeler\node-ogreniyorum\database\register_sql.js:8:22)
at C:\Users\Hasan\Desktop\Projeler\node-ogreniyorum\routes\users.js:37:29
at Layer.handle [as handle_request] (C:\Users\Hasan\Desktop\Projeler\node-ogreniyorum\node_modules\express\lib\router\layer.js:95:5)
at next (C:\Users\Hasan\Desktop\Projeler\node-ogreniyorum\node_modules\express\lib\router\route.js:137:13)
at next (C:\Users\Hasan\Desktop\Projeler\node-ogreniyorum\node_modules\express\lib\router\route.js:131:14)
at Route.dispatch (C:\Users\Hasan\Desktop\Projeler\node-ogreniyorum\node_modules\express\lib\router\route.js:112:3)  

我不明白,因为我在调用我的方法后已经结束了我的客户。

register_sql.js:


module.exports.findUserById =(async (username) =>{
    try {
        await client.connect();
        console.log('Connected successfuly');
        const result = await client.query("select * from users where username = ($1)", [username]);
        console.log(result.rows[0]['username']);
        await client.end();
        console.log('Client disconnected...');
    } catch (err) {
        console.log(err);
    }
});

我在 users.js 中调用 register_sql.js。 这里是 users.js:

const router = express.Router();
const registerSQL = require('../database/register_sql');
router.route('/register')
    .get((req, res, next) => {
        res.render('register');
    })
    .post((req, res, next) => {
            const {
                username,
                password,
                password2
            } = req.body;
            let errors = [];
            if (!username || !password || !password2) {
                errors.push("Please fill in all fields!");
            }
            if (password != password2) {
                errors.push("Passwords do not match!");
            }
            if (password.length < 6) {
                errors.push("Password has to be at least 6 characters!");
            }
            if (errors.length > 0) {
                res.render('register', {
                    errors
                });
            } else {
                registerSQL.findUserById(username);
                res.redirect('/');
            }
});

module.exports = router;  

感谢您的帮助!

【问题讨论】:

  • 你使用 ORM 吗?
  • 你能在你启动服务器的地方分享你的代码吗? (可能您在启动服务器之前创建了一个客户端)
  • @diegoorellana 你好,首先我尝试了 Knex.js,但我不能,从那以后我尝试在没有 ORM 的情况下进行编写。我在 app.js 中启动我的服务器。你可以在这里看到:link
  • 你能分享你实例化客户端的代码吗(const client = ...)
  • 您也可以尝试删除 client.connect() 行,因为您之前创建了连接...

标签: javascript node.js postgresql express node-postgres


【解决方案1】:

使用 node-postgres(您正在使用的那个)我只使用池来管理连接。

const pg = require('pg')
const pool = new pg.Pool();

pool.connect(function(err, client, done) {
    if(err) {
      return console.error('connexion error', err);
    }
    client.query("select * from users where username = ($1)", [username], function(err, result) {
      // call `done()` to release the client back to the pool
      done();
  
      if(err) {
        return console.error('error running query', err);
      }
      console.log(result.rows[0]['username'])
    });
});

【讨论】:

  • 非常感谢。使用池解决了我的问题。
【解决方案2】:

我设法在不使用池的情况下解决了这个问题。也许这不是最正确的解决方案,但它确实有效。 首先创建一个单独的js文件,在这里连接客户端并导出:

const pg = require('pg')
const client = new pg.Client('your connection string')
client.connect()
module.exports = client

然后您只需使用已连接的导出客户端,因此不会在每次请求时再次重新连接。一定要从你连接的js文件中导入客户端。

    const client = require('../db')
    const register = async (req, res) => {
        const {email, password, username} = req.body
        const hashedPassword = await bcrypt.hash(password, 10)
        const command = `insert into users(email, username, password, created) VALUES ('${email}', '${username}', '${hashedPassword}', current_timestamp)`
        await client.query(command, (err, result) => {
err ? res.json({error: err.detail}) : res.json({message: 'User created!'})
})
    }

【讨论】:

    【解决方案3】:

    问题的发生是因为您没有关闭与数据库的连接。 请记住,在向客户端发送此类内容之前,您必须关闭连接:

    try {
      await client.connect();
      const result = await client.query(query, values);
      await client.end();
      res.status(201).send({
        result,
      });
    } catch (err) {
      return res.send({
        error: err.detail,
          message: "Can't create a new user, please check your info again!",
        });
      }
    

    【讨论】:

      【解决方案4】:

      Pool 方法是更好的做法,但如果有人想使用 Client 方法连接,那么此解决方案将起作用。

      适用于客户端方法的代码:

      client.connect();
      
      client.query(`select * from users where username = ($1)`, (err, result)=>{
        try{
                console.log("Test", result)
                 res.send(result)
              } catch{
                console.log("err", err)
                res.status(500).json(err);
          
              }
      
          client.end();
      

      })

      【讨论】:

        猜你喜欢
        • 2017-06-26
        • 2012-03-15
        • 1970-01-01
        • 2011-05-20
        • 1970-01-01
        • 2014-03-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多