Используем COPY для Экспорта/Импорта Данных в Potgresql
В PostgreSQL есть функция, позволяющая эффективно выполнять массовый импорт и экспорт данных в таблицу и из неё. Обычно это гораздо более быстрый способ загрузки данных в таблицу и извлечения из неё, чем использование команд INSERT и SELECT.
В .NET провайдер Npgsql поддерживает три режима операции COPY: бинарный, текстовый и бинарный необработанный.
1. Бинарный
Пользователь использует API для чтения и записи строк и полей, которые Npgsql кодирует и декодирует. После завершения необходимо вызвать функцию Complete() для сохранения данных; в противном случае операция COPY будет откачена при освобождении объекта записи (это поведение важно в случае возникновения исключения).
// Импорт в таблицу с 2 полями (string, int)
using (var writer = conn.BeginBinaryImport(
"COPY my_table (field1, field2) FROM STDIN (FORMAT BINARY)"))
{
writer.WriteRow("Row1", 123);
writer.WriteRow("Row2", 123);
writer.Complete();
}
// Экспорт из таблицы с 2 полями
using (var rdr = conn.BeginBinaryExport(
"COPY my_table (field1, field2) TO STDOUT (FORMAT BINARY)"))
{
rdr.StartRow();
Console.WriteLine(rdr.Read<string>());
Console.WriteLine(rdr.Read<int>(NpgsqlDbType.Smallint));
rdr.StartRow();
// пропускает поле
rdr.Skip();
// проверяет на NULL (без перехода на следующее поле)
Console.WriteLine(rdr.IsNull);
Console.WriteLine(rdr.Read<int>());
rdr.StartRow();
// StartRow() вернёт -1 в конце данных
}
2. Текстовый
В этом режиме данные в БД и из неё передаются в текстовом или CSV-формате PostgreSQL. Пользователь должен самостоятельно отформатировать текст или CSV-файл, Npgsql предоставляет только функции чтения или записи текста. Этот режим менее эффективен, чем бинарный, и подходит, если у вас уже есть данные в CSV, а производительность не критична.
using (var writer = conn.BeginTextImport(
"COPY my_table (field1, field2) FROM STDIN"))
{
writer.Write("HELLO\t1\n");
writer.Write("GOODBYE\t2\n");
}
using (var reader = conn.BeginTextExport(
"COPY my_table (field1, field2) TO STDOUT"))
{
Console.WriteLine(reader.ReadLine());
Console.WriteLine(reader.ReadLine());
}
3. Бинарный необработанный
Данные передаются в двоичном формате, но Npgsql не выполняет никакого кодирования или декодирования — данные предоставляются как необработанный поток .NET. Имеет смысл только для обработки больших объемов данных и восстановления таблицы: таблица сохраняется как BLOB-объект, который впоследствии можно восстановить. Если нужно разбирать данные, используйте обычный бинарный режим.
int len;
var data = new byte[10000];
// Экспорт table1 в массив данных
using (var inStream = conn.BeginRawBinaryCopy(
"COPY table1 TO STDOUT (FORMAT BINARY)"))
{
// Предполагаем, что данные влезут в 10000 байт
// В реальности их нужно читать блоками
len = inStream.Read(data, 0, data.Length);
}
// Импорт данных в table2
using (var outStream = conn.BeginRawBinaryCopy(
"COPY table2 FROM STDIN (FORMAT BINARY)"))
{
outStream.Write(data, 0, len);
}
Отмена
Операции импорта можно отменить в любой момент, освободив (dispose) NpgsqlBinaryImporter до вызова метода Complete(). Операции экспорта можно отменить, вызвав метод Cancel().
Источник: https://www.npgsql.org/doc/copy.html