Что такое синтаксис COPY FROM / COPY TO в PostgreSQL
Что проверяют
Знаете ли вы, что команда выполняется на стороне сервера базы, и умеете ли грузить из приложения большие объёмы потоком, а не пачкой построчных вставок. Для серверной разработки это прямой вопрос про производительность загрузки данных.
Как отвечать
Команда переносит данные между таблицей и файлом или потоком. Главное различие в том, чей это диск. Вариант с путём к файлу читает и пишет файл на машине сервера от имени процесса СУБД и требует прав суперпользователя или специальной служебной роли, поэтому в облачной или контейнерной инсталляции он обычно недоступен. Клиентские варианты это команда с обратной косой чертой в psql и обмен через стандартный поток, которым пользуется драйвер.
COPY jobs (id, title) FROM STDIN WITH (FORMAT csv, HEADER true);
COPY (SELECT id, title FROM jobs) TO STDOUT WITH (FORMAT csv);Значение опции формата пишется идентификатором, а не строкой в кавычках. Выгружать можно результат произвольного запроса, загружать только в таблицу.
_, err := conn.CopyFrom(ctx, pgx.Identifier{"jobs"}, []string{"id", "title"},
pgx.CopyFromSlice(len(rows), func(i int) ([]any, error) {
return []any{rows[i].ID, rows[i].Title}, nil
}))Выигрыш возникает потому, что вместо разбора и планирования тысяч запросов идёт один поток строк с минимальными накладными расходами на строку.
Где спотыкаются
Ждут поведения обычной вставки. Разрешения конфликтов тут нет, поэтому повторная загрузка того же файла падает на уникальном индексе; правильный приём это загрузка в промежуточную таблицу и перенос оттуда запросом с обработкой конфликтов.
Считают операцию построчной. Одна плохая строка откатывает всю загрузку целиком, и без предварительной валидации файла загрузка миллионов строк срывается на последней записи.
Путают, чей это диск. Кладут файл на машину приложения, пишут путь в команду и получают отказ по отсутствию файла, хотя файл есть, просто сервер смотрит в свою файловую систему.