使用Go从一个postgres数据库复制到另一个

问题描述 投票:0回答:1

我想用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中运行上述命令行命令?还是通过管道将数据发送到不同的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()
postgresql go copy etl
1个回答
0
投票

读取器和写入器应位于不同的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")
    }
© www.soinside.com 2019 - 2024. All rights reserved.