Sequelize 和 WITH HOLD 游标

Sequelize and WITH HOLD cursors

我正在尝试使用 postgresql 和 sequelize 实现游标分页,我已经成功地尝试在事务上创建游标 WITH HOLD 并从中获取数据。

sequelize.transaction(function (t) {

    const query = "DECLARE my_cur CURSOR WITH HOLD FOR SELECT foo, bar FROM x " +
        "WHERE time=\'2016-09-16\'::date;"

    return sequelize.query(query, {transaction: t}).spread(function (results,metadata) {
        console.log("Cursor created!")
    });

}).then(function (result) {
    console.log(result)
    console.log("Transaction commited")
    sequelize.query("FETCH NEXT FROM my_cur").spread(function (results,metadata) {
        console.log("Fetching from previously created cursor:")
        console.log(results)
        console.log(metadata)
    }).catch(function(err){
        console.log("Failed to fetch from cursor")
        console.log(err)
    });
}).catch(function (err) {
    throw err
    console.log("Failed to create a cursor")
});

如果我尝试在不同的会话中从游标中获取,我会得到:

FETCH NEXT FROM my_cur;
ERROR: <<my_cur>> doesn't exist.

游标即使声明为 WITH HOLD 也会在会话关闭后被销毁并且不会在会话之间共享,我的问题是,sequelize 如何处理与 postgreSQL 的会话,我是否能够在单独的 API打电话?

socket.on("fetch_next_page", function()){
   var cursor = socket.session.cursor
   var pageSize = 10
   sequelize.query("FETCH +"pageSize"+ FROM my_cur").spread(function (results,metadata) {
            console.log("Fetching from previously created cursor:")
            console.log(results)
            socket.emit("page",results)
            console.log(metadata)
        }).catch(function(err){
            console.log("Failed to fetch from cursor")
            console.log(err)
        });
}

在同一会话中执行一系列查询的最简单方法是通过 pg-promise 中实现的任务或事务。

参见Tasks and Transactions

如果它们之间存在依赖关系,您可以承诺链接查询,如果它们之间没有依赖关系,则将它们作为批处理执行。

如果你需要在session中迭代N次,比如调用FETCH直到某个条件,你也可以使用方法sequence.