首页 > 解决方案 > 使用带有 pg-promise 的游标

问题描述

我正在努力寻找一个将光标与 pg-promise 一起使用的示例。node-postgres 支持其 pg-cursor 扩展。有没有办法将该扩展与 pg-promise 一起使用?我正在尝试实现一个异步生成器(以支持 for-await-of)。pg-query-stream 似乎不适合这个用例(我需要“拉”,而不是“推”)。

例如,我使用 SQLite 进行单元测试,我的(删节的)生成器看起来像这样......

async function* () {

    const stmt = await db.prepare(...);

    try {

        while (true) {

            const record = await stmt.get();

            if (isUndefined(record)) {

                break;
            }

            yield value;
        }
    }
    finally {

        stmt.finalize();
    }
}

使用 pg-cursor,分配 tostmt会变成类似client.query(new Cursor(...)),stmt.get会变成stmt.read(1)并且stmt.finalize会变成stmt.close.

谢谢

标签: javascriptpg-promisedatabase-cursor

解决方案


按照原始示例,我们可以修改它们以与pg-promise一起使用:

const pgp = require('pg-promise')(/* initialization options */);
const db = pgp(/* connection details */);

const Cursor = require('pg-cursor');

const c = await db.connect(); // manually managed connection

const text = 'SELECT * FROM my_large_table WHERE something > $1';
const values = [10];

const cursor = c.client.query(new Cursor(text, values));

cursor.read(100, (err, rows) => {
  cursor.close(() => {
    c.done(); // releasing connection
  });
  // or you can just do: cursor.close(c.done);
});

由于pg-promise不明确支持pg-cursor,因此必须手动获取连接对象并直接使用它,如上例所示。

pg-query-stream 似乎不适合这个用例(我需要pull,而不是push)。

实际上,在这些库的上下文中,流和游标都仅用于提取数据。所以你也可以使用流媒体。


推荐阅读