Небольшой пример как копировать данные между базами данных используя go, pgx, и copy.
Предположим что у нас есть два коннекта к базе (одной или нескольким, это не важно). Далее используя io.Pipe() создаём Reader и Writer, и используя CopyTo() и CopyFrom() переносим данные.
r, w := io.Pipe()
go func() {
_, err := db1.PgConn().CopyTo(ctx, w, `copy table1 to stdout binary`)
if err != nil {
slog.Error("error", "err", err)
return
}
_ = w.Close()
}()
_, err = db2.PgConn().CopyFrom(ctx, r, `copy table1 from stdin binary`)
_ = r.Close()Вся прелесть тут в том что используем наиболее быстрый способ с точки зрения PostgreSQL.
Используя copy (select * from where ... order by ... limit ...) to stdout можем регулировать нагрузку на чтение, следить за прогрессом и управлять копированием данных.
В качестве Reader может выступать что угодно, хоть файл csv, хоть другая СУБД, но тогда данные придётся дополнительно конвертировать в формат понимаемый PostgreSQL - csv или tsv, и использовать copy ... from stdin (format csv).
Нюанс: copy ... from stdin binary , binary обязывает использовать одинаковые типы данных, нельзя будет integer колонку перенести в колонку smallint, если такое требуется, то параметр binary надо опустить.
