【问题标题】:Using placeholders with copy and pg-query-stream使用带有 copy 和 pg-query-stream 的占位符
【发布时间】:2020-12-26 08:03:10
【问题描述】:

我正在尝试将查询提取为 csv 文件。我尝试使用copy 和pg-query-stream 来执行查询,但我遇到了这个错误:

error: bind message supplies 1 parameters, but prepared statement "" requires 0

当从查询中删除 copy 时,如果我提供带有 copy 的查询并且没有占位符,它也可以与占位符一起正常工作。

const pgp = require('pg-promise')
const QueryStream = require('pg-query-stream')
query1 = "copy (select * from real_state WHERE town_code= $1 ) TO  '/tmp/file.csv'"
const qs = new QueryStream(query1, [22])
await db.stream(qs, s => {
            // initiate streaming into the console:
            s.pipe(JSONStream.stringify()).pipe(process.stdout)
        }).then(data => {
        }).catch(error => {
            console.log('ERROR:', error)
        })

query1 = "copy (select * from real_state WHERE town_code= $1 ) TO  '/tmp/file.csv'" ==> error
query2 = "copy (select * from real_state) TO  '/tmp/file.csv'" ==> It works
query3 = "select * from real_state WHERE town_code= $1" ==>  It works

【问题讨论】:

    标签: javascript node.js postgresql pg-promise


    【解决方案1】:

    COPY 上下文中有一个限制,禁止您使用任何参数。

    但您可以使用pg-promise 查询格式来解决该限制:

    const query = pgp.as.format('COPY(SELECT * FROM real_state WHERE town_code = $1) TO $2',
                                [22, '/tmp/file.csv']);
    

    【讨论】:

      【解决方案2】:

      我认为您将两个功能混合在一起。

      pg-query-stream 将行作为流返回,不需要在 select 中使用 copy。只需使用简单的选择,然后将结果通过管道传输到文件流。

      const fs = require('fs')
      const { Pool } = require('pg')
      const QueryStream = require('pg-query-stream')
      
      const query = new QueryStream("select * from real_state WHERE town_code= $1", [22]
      const stream = pool.query(query)
      const fileStream = fs.createReadStream('/tmp/file.csv')
      fileStream.pipe(stream)
      

      如果您想使用复制,请使用 pg-copy-streams:https://github.com/brianc/node-pg-copy-streams

      const fs = require('fs')
      const { Pool } = require('pg')
      const copyFrom = require('pg-copy-streams').from
      const stream = db.query(copyFrom('COPY real_state FROM stdin WHERE town_code= $1', [22])
      const fileStream = fs.createReadStream('/tmp/file.csv')
      
      fileStream.pipe(stream)
      

      【讨论】:

      • 他的代码可以正常工作,使用我提供的解决方法(见我的回答)。
      • 没错,但是当你已经有一个流时使用复制有什么意义呢?看来你的变通办法只是促使他使用你的模块?
      • "使用我的模块推送?" - 这听起来很消极。如果你阅读了这个问题,他已经在使用它,我给了他针对他描述的确切问题的正确解决方案。但是,无论出于何种原因,请随意引导他离开,并开始使用不同的模块。
      • 是的,结果是负面的,他已经在使用它了。我的错,我很抱歉。
      猜你喜欢
      • 2021-03-29
      • 2020-08-03
      • 2019-07-16
      • 1970-01-01
      • 2013-01-03
      • 2020-10-21
      • 2014-12-25
      • 1970-01-01
      • 2018-10-21
      相关资源
      最近更新 更多