2017-02-05 10 views
0

У меня есть следующий код для вложенных вставок PostgreSQL с использованием npgsql из. Net кода.NpgSqlCopy Рекомендуемая обработка ошибок

try 
{ 
var items = GetSourceData(task); 
connection.Open(); 
var command = new NpgsqlCommand(null, connection); 

BeforeDestinationCommandExecution(task, command); 

command.CommandText = string.Format("COPY {0} FROM STDIN", task.DestinationTable); 
command.CommandTimeout = 3600; 
var cin = new NpgsqlCopyIn(command, connection); 
var rowCount = 0; 

try 
{ 
    cin.Start(); 
    foreach (var item in items) 
    { 
     var b = StreamEncoding.GetBytes(ConvertSourceData(item)); 
     cin.CopyStream.Write(b, 0, b.Length); 
     ++rowCount; 
    } 
    cin.End(); 
    log.Debug(string.Format("Table {0} contained {1:N0} records", task.DestinationTable, rowCount)); 
} 
catch (Exception e) 
{ 
    log.ErrorException("Exception caught in inner try block - MigrateWithCopyMode", e); 
    try 
    { 
     // send CopyFail to server 
     cin.Cancel("Undo copy"); 
    } 
    catch (Exception cancelException) 
    { 
     // we should get an error in response to our cancel request: 
     if (!cancelException.ToString().Contains("Undo copy")) 
     { 
      throw new Exception("Failed to cancel COPY: " + cancelException + " upon failure: " + e); 
     } 
    } 
    throw; 
} 
finally 
{ 
    _migrationCounts.Add(task.DestinationTable, rowCount); 
} 

За последние 2 дня я испытал необработанное исключение при выполнении кода. После некоторого расследования и прикрепления кода к событию UnhandledException. System.AppDomain.CurrentDomain.UnhandledException += unhandledException; Я обнаружил, что проблема заключается в обработке данных.

Error [16] [HubAdapterMsSqlPostgres] Unhandled exception Npgsql.NpgsqlException: 
null value in column "name_ru" violates not-null constraint 
Severity: ERROR 
Code: 23502 
    at Npgsql.NpgsqlState.<ProcessBackendResponses_Ver_3>d__a.MoveNext() 
    at Npgsql.NpgsqlState.IterateThroughAllResponses(IEnumerable`1 ienum) 
    at Npgsql.NpgsqlConnector.NpgsqlContextHolder.ProcessServerMessages() 
    at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) 
    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) 
    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) 
    at System.Threading.ThreadHelper.ThreadStart() 

Эта ошибка была произведена для различных потоков. Думаю, после вызова cin.CopyStream.Write(b, 0, b.Length); из предыдущего примера кода.

Мой вопрос

Что рекомендуется способ справиться с такой ошибки, чтобы иметь возможность Опустить строки с неправильными значениями и продолжать операции массовой вставки

Спасибо

ответ

0

Вы пытаетесь импортировать данные, содержащие строки, которые несовместимы с вашим определением таблицы - им не хватает данных для столбца с недействительными значениями. COPY - это процесс «все или ничего»: либо весь процесс завершается успешно, либо он полностью не работает. Поэтому вам нужно либо: * Сначала очистите свой вход, удалив оскорбительные строки (это потребует анализа вашего ввода, что может быть затруднено) или * Временно удалите ненулевое ограничение в вашей таблице, выполните COPY , удалите проблемные строки из таблицы и восстановите ограничение. Это может быть или не быть подходящим в зависимости от вашего сценария использования.

Независимо от того, вы используете Npgsql 2.x, который к тому времени является очень старым и не поддерживается. Настоятельно рекомендуется обновить до последней версии Npgsql.