【问题标题】:psql \copy command using scala process builder syntax error使用 scala 进程构建器语法错误的 psql \copy 命令
【发布时间】:2020-10-28 13:14:01
【问题描述】:

我需要在 postgres 中的表中插入 1M 行数据,所以我使用的是 postgres 的 csv 命令副本。因为 COPY 需要一个超级用户帐户才能工作,所以我使用 /copy 代替。

这是我的 scala 代码:

val execCommand = Seq("psql", s"postgresql://$user:$pwd@$host:5432/$db", "-c", s"""\"\\copy $fullTableName (${columnsList}) from '${file.getAbsolutePath}' with delimiter ',' csv HEADER;\" """)
val result = execCommand.!!
println(result)

该命令看起来像这样,并且在从我的终端运行时可以工作:

psql postgresql://user:password@host:5432/db -c "\copy tableName (column1, column2, column3) from 'file_to_load.csv' with delimiter ',' csv HEADER;"

但是当我的代码运行时,它会抛出这个错误:

syntax error at or near ""\copy tableName (column1, column2, column3) with delimiter ',' csv HEADER;""

如果我用选择查询替换命令,它工作正常。有人可以帮我识别 \copy 命令上的错误吗?语法对我来说是正确的。也许我错过了一些东西。我也是 scala 的流程构建器的新手,所以我也不知道是否需要修复命令。如果我这样做,我应该如何改变这个?谢谢。

【问题讨论】:

  • 您能打印出execCommand 的值吗?最好使用execCommand.mkString("\n") 之类的东西,所以只能从您的Strings 看到,,而不是seq.toString 添加的那些

标签: scala psql


【解决方案1】:

可能不需要运行 psql 命令。您通常最好使用相应的 JDBC API:

https://jdbc.postgresql.org/documentation/publicapi/org/postgresql/copy/CopyManager.html

【讨论】:

    【解决方案2】:

    发布我如何使用 CopyManager 修复它。有关这方面的文档,请参阅 Matthias Berndt 的评论。

    object PgDbHandler {
      def getConnection(db: ConnectionName, userName: String = user, pwd: String = password): Connection = {
        Class.forName("org.postgresql.Driver")
        DriverManager.getConnection(s"jdbc:postgresql://${db.sqlDns}/${db.databaseName}?user=$userName&password=$pwd&sslmode=require")
      }
    
      def copyFileToPg(file: File, fullTableName: String, columnsList: List[String]): Long = {
    
        logger.info(s"Writing $file to postgres")
    
        val conn = getConnection(db, user, pwd)
        try{
          val rowsInserted = new CopyManager(conn.asInstanceOf[BaseConnection])
            .copyIn(s"COPY $fullTableName (${columnsList.mkString(",")}) FROM STDIN (DELIMITER ',',FORMAT csv, header true)",
              new FileInputStream(file.getAbsolutePath))
    
          logger.info(s"$rowsInserted row(s) inserted for file $file")
          rowsInserted
        }
        finally
          conn.close
      }
    }
    

    【讨论】:

    • 你也应该关闭 FileInputStream。
    猜你喜欢
    • 2016-08-06
    • 2019-03-29
    • 1970-01-01
    • 2021-02-08
    • 1970-01-01
    • 2020-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多