postgreSQL でテーブルをコピーするとき、javaからCopyManagerを使うと速いらしいので、検索してみたが、一回ファイルに落とすサンプルばかりで、直接コピーしてるものがなかなか見つからなかったので、誰かの役にたつかなっと思い投稿してみました。
↓ の ソースは、前半コピー元テーブルにファイルからコピーして、後半、コピー元テーブルからダイレクトにコピー先テーブルへコピーします。
ポイントはコピー元テーブルからの読み込みで、PGCopyInputStream()を使用しますが、その時CopyManager()で使用するコネクションとは別のコネクションをもう一つ用意しないとダメってところです。
ここで、結構ハマりましたが、よくよく考えるとinとoutで同じファイルディスクリプタを使えないのと同じ理屈でした。
public static void main(String[] args) throws Exception {
if(args.length!=4) {
System.out.println("Please specify database URL, user, password and file on the command line.");
System.out.println("Like this: jdbc:postgresql://localhost:5432/test test password file");
return;
}
System.out.println("Loading driver");
Class.forName("org.postgresql.Driver");
System.out.println("Connecting to " + args[0]);
Connection con = DriverManager.getConnection(args[0],args[1],args[2]);
Connection con2 = DriverManager.getConnection(args[0],args[1],args[2]);
con.setAutoCommit(false);
con2.setAutoCommit(false);
Statement statement = con2.createStatement();
statement.executeUpdate("TRUNCATE member");
statement.executeUpdate("TRUNCATE member2");
con2.commit();
String inSql = "COPY member to STDOUT WITH CSV";
String outSql = "COPY member2 FROM STDIN WITH CSV";
String inSqlFromFile = "COPY member FROM STDIN WITH CSV";
System.out.println("Copying text data rows from stdin");
CopyManager copyManager = new CopyManager((BaseConnection) con);
FileReader fileReader = new FileReader(args[3]);
copyManager.copyIn(inSqlFromFile, fileReader );
con.commit();
System.out.println("Copying data rows from member to member2");
PGCopyInputStream pgIn = new PGCopyInputStream((PGConnection)con2, inSql);
copyManager.copyIn(outSql, pgIn );
con.commit();
con.close();
con2.close();
System.out.println("Done.");
}