2017-02-05 31 views
0

我有下面的代碼來使用.Net代碼中的npgsql進行PostgreSQL批量插入。NpgSqlCopyIn推薦的錯誤處理

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。