sql >> Database teknologi >  >> RDS >> PostgreSQL

CSV-kopi til Postgres med array af brugerdefineret type ved hjælp af JDBC

Se https://git.mikael.io/mikaelhg/pg -object-csv-copy-poc/ til et projekt med en JUnit-test, der gør, hvad du vil.

Grundlæggende ønsker du at være i stand til at bruge kommaer til to ting:til at adskille matrixelementer og til at adskille typefelter, men du ønsker IKKE at CSV-parsingen skal fortolke kommaer som feltafgrænsninger.

  1. du vil fortælle CSV-parseren at betragte hele rækken som én streng, ét felt, hvilket du kan gøre ved at omslutte det i enkelte anførselstegn og fortælle CSV-parseren om dette, og
  2. du ønsker, at PG-feltparseren skal betragte hver instans af array-elementtype som omsluttet af et dobbelt anførselstegn.

Kode:

copyManager.copyIn("COPY my_table (adresser) FRA STDIN MED CSV CITAT ''''", læser); 

DML eksempel 1:

KOPIER min_tabel (adresser) FRA STDIN MED CSV-CITAT '''' 

CSV eksempel 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)"}'

DML eksempel 2, undslipper de dobbelte anførselstegn:

KOPIER min_tabel (adresser) FRA STDIN MED CSV 

CSV eksempel 2, undslipper de dobbelte anførselstegn:

"{""(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)""}"

Fuld JUnit-testklasse:

pakke 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 privat Reader-læser; privat Forbindelse forbindelse; privat CopyManager copyManager; private static final String CREATE_TYPE ="OPRET TYPE-adresse AS (ip inet, port int)"; private static final String CREATE_TABLE ="OPRET TABEL min_tabel (adresser adresse[] NULL)"; private String loadCsvFromFile(final String fileName) kaster 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() kaster Undtagelse { Class.forName("org.postgresql.Driver"); } @Before public void before() kaster Undtagelse { String input =loadCsvFromFile("/data_01.csv"); reader =new StringReader(input); forbindelse =DriverManager.getConnection(db.getJdbcUrl(), db.getUsername(), db.getPassword()); copyManager =connection.unwrap(PGConnection.class).getCopyAPI(); forbindelse.setAutoCommit(falsk); forbindelse.beginRequest(); connection.prepareCall(CREATE_TYPE).execute(); connection.prepareCall(CREATE_TABLE).execute(); } @After public void efter() kaster Undtagelse { connection.rollback(); } @Test public void copyTest01() kaster Undtagelse { copyManager.copyIn("COPY my_table (adresser) FRA STDIN MED CSV CITAT ''''", reader); final StringWriter writer =new StringWriter(); copyManager.copyOut("KOPIER min_tabel TIL STDOUT MED CSV", writer); System.out.printf("rundtur:%n%s%n", writer.toString()); final ResultSet rs =connection.prepareStatement( "SELECT array_to_json(array_agg(t)) FROM (SELECT adresser FROM my_table) t") .executeQuery(); rs.next(); System.out.printf("json:%n%s%n", rs.getString(1)); }} 

Test output:

tur-retur:"{""(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:[{"adresser":[{" ip":"10.0.0.1","port":1},{"ip":"10.0.0.2","port":2}]},{"adresser":[{"ip":"10.10. 10.1","port":80},{"ip":"10.10.10.2","port":443}]},{"adresser":[{"ip":"10.10.10.3","port" :8080},{"ip":"10.10.10.4","port":4040}]}] 


  1. Almindelig måde at sammenligne tidsstempel i Oracle, PostgreSQL og SQL Server

  2. Rails Postgres funktionelle indekser

  3. VÆLG mysql-kolonne med kommaseparerede værdier

  4. SQL-CASE:Kend og undgå 3 mindre kendte problemer