PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Salin CSV ke Postgres dengan array tipe khusus menggunakan JDBC

Lihat https://git.mikael.io/mikaelhg/pg -object-csv-copy-poc/ untuk proyek dengan pengujian JUnit yang melakukan apa yang Anda inginkan.

Pada dasarnya, Anda ingin dapat menggunakan koma untuk dua hal:untuk memisahkan item array, dan untuk memisahkan bidang jenis, tetapi Anda TIDAK ingin penguraian CSV menafsirkan koma sebagai penggambar bidang.

Jadi

  1. Anda ingin memberi tahu pengurai CSV untuk menganggap seluruh baris sebagai satu string, satu bidang, yang dapat Anda lakukan dengan melampirkannya dalam tanda kutip tunggal dan memberi tahu pengurai CSV tentang hal ini, dan
  2. Anda ingin pengurai bidang PG mempertimbangkan setiap instance tipe item array untuk diapit dalam tanda kutip ganda.

Kode:

copyManager.copyIn("COPY my_table (addresses) FROM STDIN WITH CSV QUOTE ''''", reader);

Contoh DML 1:

COPY my_table (addresses) FROM STDIN WITH CSV QUOTE ''''

Contoh CSV 1:

'{"(10.0.0.1,1)","(10.0.0.2,2)"}'
'{"(10.10.10.1,80)","(10.10.10.2,443)"}'
'{"(10.10.10.3,8080)","(10.10.10.4,4040)"}'

Contoh DML 2, menghindari tanda kutip ganda:

COPY my_table (addresses) FROM STDIN WITH CSV

Contoh CSV 2, menghindari tanda kutip ganda:

"{""(10.0.0.1,1)"",""(10.0.0.2,2)""}"
"{""(10.10.10.1,80)"",""(10.10.10.2,443)""}"
"{""(10.10.10.3,8080)"",""(10.10.10.4,4040)""}"

Kelas tes JUnit lengkap:

package io.mikael.poc;

import com.google.common.io.CharStreams;
import org.junit.*;
import org.postgresql.PGConnection;
import org.postgresql.copy.CopyManager;
import org.testcontainers.containers.PostgreSQLContainer;

import java.io.*;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;

import static java.nio.charset.StandardCharsets.UTF_8;

public class CopyTest {

    private Reader reader;

    private Connection connection;

    private CopyManager copyManager;

    private static final String CREATE_TYPE = "CREATE TYPE address AS (ip inet, port int)";

    private static final String CREATE_TABLE = "CREATE TABLE my_table (addresses  address[] NULL)";

    private String loadCsvFromFile(final String fileName) throws IOException {
        try (InputStream is = getClass().getResourceAsStream(fileName)) {
            return CharStreams.toString(new InputStreamReader(is, UTF_8));
        }
    }

    @ClassRule
    public static PostgreSQLContainer db = new PostgreSQLContainer("postgres:10-alpine");

    @BeforeClass
    public static void beforeClass() throws Exception {
        Class.forName("org.postgresql.Driver");
    }

    @Before
    public void before() throws Exception {
        String input = loadCsvFromFile("/data_01.csv");
        reader = new StringReader(input);

        connection = DriverManager.getConnection(db.getJdbcUrl(), db.getUsername(), db.getPassword());
        copyManager = connection.unwrap(PGConnection.class).getCopyAPI();

        connection.setAutoCommit(false);
        connection.beginRequest();

        connection.prepareCall(CREATE_TYPE).execute();
        connection.prepareCall(CREATE_TABLE).execute();
    }

    @After
    public void after() throws Exception {
        connection.rollback();
    }

    @Test
    public void copyTest01() throws Exception {
        copyManager.copyIn("COPY my_table (addresses) FROM STDIN WITH CSV QUOTE ''''", reader);

        final StringWriter writer = new StringWriter();
        copyManager.copyOut("COPY my_table TO STDOUT WITH CSV", writer);
        System.out.printf("roundtrip:%n%s%n", writer.toString());

        final ResultSet rs = connection.prepareStatement(
                "SELECT array_to_json(array_agg(t)) FROM (SELECT addresses FROM my_table) t")
                .executeQuery();
        rs.next();
        System.out.printf("json:%n%s%n", rs.getString(1));
    }

}

Hasil pengujian:

roundtrip:
"{""(10.0.0.1,1)"",""(10.0.0.2,2)""}"
"{""(10.10.10.1,80)"",""(10.10.10.2,443)""}"
"{""(10.10.10.3,8080)"",""(10.10.10.4,4040)""}"

json:
[{"addresses":[{"ip":"10.0.0.1","port":1},{"ip":"10.0.0.2","port":2}]},{"addresses":[{"ip":"10.10.10.1","port":80},{"ip":"10.10.10.2","port":443}]},{"addresses":[{"ip":"10.10.10.3","port":8080},{"ip":"10.10.10.4","port":4040}]}]


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Mencocokkan pola antara beberapa kolom

  2. Menghancurkan DB Postgres di Heroku

  3. Cara Mencatat Kueri di PostgreSQL

  4. Bagaimana cara menyalin data dari satu tabel ke tabel lain di postgres menggunakan perintah salin

  5. Opsi untuk mengambil nilai urutan saat ini (pada saat menjalankan kueri)