postgresql - 使用 Go 从一个 postgres 数据库复制到另一个
问题描述
我想使用 Go 将数据库 A 中的 postgres 数据,视图 A 复制到数据库 B,表 B 中。这将针对几十个表完成,我想利用 Go 提供的并发性。
我可以使用看起来像这样的 psql 命令行来做到这一点:
psql -h hostServer -p 5432 -U dbUser -d dbName \
-c "\copy (Select * From myView) TO STDOUT" \
| psql -h destinationHost -p 5432 -U dbUser -d destinationDB \
-c "\copy destinationTable FROM STDIN"
或者在 Python 中通过运行上述命令或使用 os.pipe 和 psycpog2 的 copy_from/to 命令。不幸的是,这些选项似乎都不能很好地处理并发性。这就是为什么我希望在 go 中做同样的事情。
所以我的问题 - 我如何在 GO 中运行上述命令行命令?或者通过管道将数据传入/传出不同的 postgres 数据库?我一直在尝试以下代码,但没有成功。任何提示将不胜感激。
import "github.com/go-pg/pg"
//connect to source and destination db's (successful connection confirmed)
r, w := io.Pipe()
println("start")
_, err := destDB.CopyFrom(r, "COPY destinationTable FROM STDIN")
if err != nil {
println(err)
}
_, err = srcDB.CopyTo(w, "COPY (SELECT * FROM sourceView) TO STDOUT")
if err != nil {
println(err)
}
srcDB.Close()
destDB.Close()
解决方案
读取器和写入器应该在不同的 goroutine 中,并且管道的写入端应该在完成后关闭,以防止读取端挂起。请参阅以下内容作为起点:
r, w := io.Pipe()
writer := make(chan error)
go func() {
defer w.Close()
_, err := src.CopyTo(w, `COPY (SELECT * FROM sourceView) TO STDOUT`)
writer <- err
}()
reader := make(chan error)
go func() {
_, err := dest.CopyFrom(r, "COPY destinationTable FROM STDIN")
reader <- err
}()
errWriter := <-writer
if errWriter != nil {
fmt.Printf("Writer (CopyTo) error: %v", errWriter)
}
errReader := <-reader
if errReader != nil {
fmt.Printf("Reader (CopyFrom) error: %v", errReader)
}
if errWriter == nil && errReader == nil {
fmt.Println("All done - no errors")
}
推荐阅读
- reactjs - React-query:如何使用 useInfiniteQuery 进行分页
- java - 在 Java 中将字符串集合复制到另一个字符串的时间复杂度
- c# - Unity C#:如何将消息从一个应用程序发送到不同 IP 上的另一个应用程序?
- python - 在运行 Sophos 的机器上,为什么我的所有浏览器都无法从我的 Python 应用程序实时接收服务器发送的事件 (sse)?
- java - HTTP请求是POST请求,xxl-job参数是GET,为什么要执行
- python - 在保持梯度值的同时重复张量元素
- javascript - 处理动态表以在 Vuejs 框架中添加和删除行,下面是我的表
- php - 检索新的数据库记录
- reactjs - 获取发送空的帖子参数 - 反应原生
- c# - 使用图像路径显示图像不起作用