2017-02-05 35 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。