使用Scala Process Builder语法错误的psql \ copy命令

时间:2020-10-26 13:34:15

标签: scala psql

我需要在postgres中的表中插入1M行数据,因此我正在使用来自csv命令的postgres复制。由于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的流程生成器的新手,所以我也不知道我是否需要修复命令。如果我这样做,应该如何更改?谢谢。

2 个答案:

答案 0 :(得分:0)

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

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

答案 1 :(得分:0)

发布我如何使用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
  }
}