1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

PostgreSQLのBeginTextImportが失敗する

Last updated at Posted at 2022-03-18

問題

PostgreSQLの、Npgsqlの、BeginTextImportの処理で、Npgsql.PostgresExceptionの例外が発生する場合があります。その場合、データベースにも、データをインポートできません。

原因

NpgsqlConnectionを、すぐにCloseすると、例外が発生することがあるようです(しない場合もある)。

解決法

Closeしないでおけばインポートに成功します。ただし、Closeしないままで良いのかどうかわかりません。

コード例

例えば、クライアント側で、CSVファイルから、データベースにインポートするのは、次のコードになります。
conn.Open()するので、conn.Close()したわけですが、これだと失敗する場合があります。

var connString = "Host=localhost; Port=5432; Username=postgres; Database=HOGEDatabase;";
using var conn = new NpgsqlConnection(connString);
conn.Open();
using var writer = conn.BeginTextImport(@"COPY tablename (field_text, field_int4) FROM STDIN (FORMAT CSV , HEADER)");
using StreamReader csvReader = new(@"C:\test.csv", Encoding.UTF8);
string? str;
while ((str = csvReader.ReadLine()) != null)
{
   writer.WriteLine(str);
}
//conn.Close();  //ここで例外が発生することがある

備考

  • 当初、テーブルをCSVファイルにエクスポート・インポートする処理を、EntityFramework Core と、CSV Helper で行おうとしました。しかし、jsonbの列の処理が、大変そうだなと思われたので(検証していないので、実際はどうかはわかりません)、別の方法を探し、PostgreSQLのCOPYを利用するのが良さそうだと分かりました。
  • このCOPYは、サーバー側と、クライアント側とで、使い方が違うので、混乱しますね。

2022-03-19追記。

  • CSV HelperのType Conversionを利用すれば、クラスをJsonにしCSVに保存(またその逆)も問題ないことがわかり、CSV Helperを利用してインポート・エクスポートの仕組みにしました。
  • PostgreSQLのCOPYは、idが一致する時置き換える仕組みがないようなので、利用を断念。
  • クラスをJsonbにした時に、Jsonbに保存されるJsonの文字列を直接取り出す方法が見つからなかったので、これも断念。結局、Jsonb → EntityFrameworkCoreのクラス → CSVHelperでJsonにタイプコンバート → CSVという方法を採用しました。CSVからJsonbへはこの逆です。

参照

環境

  • Npgsql 7.0.0-preview.1
  • .NET 6
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?