我需要在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的流程生成器的新手,所以我也不知道我是否需要修复命令。如果我这样做,应该如何更改?谢谢。
答案 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
}
}