Использование Go для копирования из одного postgres дБ в другой - PullRequest
0 голосов
/ 22 февраля 2020

Я хотел бы использовать Go для копирования postgres данных из базы данных A, просмотра 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()

1 Ответ

0 голосов
/ 22 февраля 2020

Читатель и писатель должны находиться в разных процедурах, и сторона записи канала должна быть закрыта, когда это сделано, чтобы сторона чтения не зависала. См. Следующее для начальной точки:

    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")
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...