PostgreSQL的“COPY table FROM file”语句可以在Go中使用吗?
Posted
技术标签:
【中文标题】PostgreSQL的“COPY table FROM file”语句可以在Go中使用吗?【英文标题】:Can PostgreSQL's "COPY table FROM file" statement be used in Go? 【发布时间】:2015-10-19 00:22:45 【问题描述】:阅读 github.com/lib/pq
文档后,我仍然不清楚是否可以使用简单的 COPY <table> FROM <file> CSV HEADER
命令从 CSV 文件中复制数据。
这就是我想要做的:
func CopyFromCSV(con Con, tableName, fileName string) error
_, err := con.Exec(fmt.Sprintf("TRUNCATE %s", tableName))
if err != nil
return err
stm, err := con.Prepare(fmt.Sprintf("COPY %s FROM '%s' CSV HEADER", tableName, fileName))
if err != nil
return err
defer stm.Close()
_, err = stm.Exec()
return err
其中tableName
是现有表,fileName
是现有 csv 文件的绝对路径。
con.Prepare
调用后我总是收到以下错误:pq: unknown response for copy query: 'C'
是否可以在 Go 中使用 github.com/lib/pq
驱动程序通过 postgres 数据库执行此操作?
【问题讨论】:
尝试在psql命令行客户端执行同样的命令。 它按预期工作:# COPY <table> FROM '/home/path/to/file.csv' CSV HEADER;
COPY 1773
COPY
功能不受pq
驱动程序的完全支持:github.com/lib/pq/issues/213。在保持与数据库/sql API 兼容的同时,使用COPY
似乎存在问题。如果您不需要符合 database/sql,您可能可以使用另一个驱动程序。
另请注意,COPY … FROM
和 COPY … TO
语句从服务器上的文件复制/复制到文件。如果您想在客户端上使用文件,您至少需要使用COPY…FROM STDIN
(或COPY…TO STDOUT
)并自己进行文件操作(这也是psql
的\copy
命令所做的)。如前所述,这不适合database/sql
API,所以如果驱动程序支持它,我非常怀疑它会通过Prepare
或Exec
。
它应该适用于服务器端路径。如果没有,那么驱动程序真的很不完整,因为使用服务器端路径的 COPY 非常简单。不过,支持COPY ... FROM stdin
或TO stdout
(用于客户端文件)要复杂得多。
【参考方案1】:
可以在此处找到执行 COPY 命令的粗略模板 - https://play.golang.org/p/6y5v3IW8kD
下面的代码应该适合你。
func copyTest()
psqlInfo := fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s sslmode=verify-full",host, port, user, password, dbname)
db, err := sql.Open("postgres", psqlInfo)
if err != nil
panic(err)
defer db.Close()
err = db.Ping()
if err != nil
panic(err)
tx, err := db.Begin()
if err != nil
panic(err)
_, err = tx.Exec("copy metadata.charvalues_temp from 'C:\\yourlocation\\yourfile.csv' with csv")
if err != nil
panic(err)
err = tx.Commit()
if err != nil
panic(err)
【讨论】:
【参考方案2】:下面的代码使用https://github.com/lib/pq
import (
"database/sql"
"fmt"
"github.com/lib/pq"
)
func bulkCopyTest()
psqlInfo := fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s sslmode=verify-full",
host, port, user, password, dbname)
db, err := sql.Open("postgres", psqlInfo)
if err != nil
panic(err)
defer db.Close()
tx, err := db.Begin()
if err != nil
panic(err)
stmt, err := tx.Prepare(pq.CopyInSchema("schemaName", "DBName", "columnName", "columnName"))
if err != nil
panic(err)
//loop through an array of struct filled with data, or read from a file
for _, row := range loadCsv
stmt.Exec(row.value1, row.value2)
if err != nil
panic(err)
_, err = stmt.Exec()
if err != nil
panic(err)
err = stmt.Close()
if err != nil
panic(err)
err = tx.Commit()
if err != nil
panic(err)
【讨论】:
以上是关于PostgreSQL的“COPY table FROM file”语句可以在Go中使用吗?的主要内容,如果未能解决你的问题,请参考以下文章
PostgreSQL介绍以及如何开发框架中使用PostgreSQL数据库
mac默认安装postgresql, 如何让postgresql可以远程访问
Wix,PostgreSQL 安装,执行 Postgresql 脚本