过期连接之外的松散请求

Loose request outside of an expired connection

我正在尝试执行以下 pg-promise 查询,但收到此错误:

Loose request outside of an expired connection

查询确实成功了,但是,即便如此,我还是想去掉错误信息。

pg-promise 查询

 db.task(t => {
          t.oneOrNone(queries.insertUser, [profile.id])
          .then(id =>{ 
          if (id) {
            t.none(queries.insertUserGoogle, [
              profile.id,
              profile.emails[0].value,
              profile.name.givenName,
              profile.name.familyName,
              profile.displayName
            ])
          }})
          .catch(err => console.log(err))

SQL

const insertUser = `INSERT INTO users (google_id) 
    VALUES () 
    ON CONFLICT (google_id) DO NOTHING
    RETURNING user_id`;

const insertUserGoogle = `INSERT INTO users_google (google_id, email, first_name, last_name, display_name) 
    VALUES (, , , , )`;

我是 pg-promise 的作者。


您未能链接查询方法返回的承诺,而查询方法又在任务上下文之外执行它们,从而导致该错误。

正确的做法是:

db.task(t => {
    return t.oneOrNone(queries.insertUser, [profile.id])
        .then(id => {
            if (id) {
                return t.none(queries.insertUserGoogle, [values])
            }
        })
})
    .catch(err => {
        console.log(err);
    });

Promise 必须始终被链接起来。并且在任务的上下文中,它们必须链接到任务。

如果不这样做会导致松散的承诺,并且在数据库任务的上下文中 - 在任务完成并释放其连接后尝试执行松散的查询请求。

此外,一个好的方法是在任务的结果上使用 .catch,如图所示,而不是在任务内部。

其他提示

  • 由于任务中的两个查询都是插入,如果您关心数据完整性,那么也许您应该使用方法 tx for transaction, and not task
  • 它使得在外部文件中存储 SQL 并以 Query Files instead. See also: pg-promise-demo.
  • 访问它们的代码更加简洁和高效

更新

但是,如果您的任务使用生成器,那么您不需要在任务中链接任何内容:

db.task(function* (t) {
    const id = yield t.oneOrNone(queries.insertUser, [profile.id]);
    if (id) {
        yield t.none(queries.insertUserGoogle, [values]);
    }
})
    .catch(err => {
        console.log(err);
    });

...您只链接任务的结果。

更新

在版本 6.5.4 中,错误消息被重构为 Querying against a released or lost connection