postgresqlpostgresql-copy

Is it possible to use postgres/psql COPY into a specific partition of a table?


I am currently looking into an efficient way to allocate data into a partitioned table. Is it possible to use postgres/psql to COPY data into a specific table partition (instead of using INSERT)?

According to the documentation on COPY here:

COPY FROM can be used with plain, foreign, or partitioned tables or with views that have INSTEAD OF INSERT triggers.

And according to the documentation on partitioning here:

Be aware that COPY ignores rules. If you want to use COPY to insert data, you'll need to copy into the correct partition table rather than into the master. COPY does fire triggers, so you can use it normally if you use the trigger approach.

From my understanding of the aforementioned resources, it seems possible to copy into partition; however, I can't find any examples or support for that online.

In other words, can I write something like:

COPY some_table_partition_one FROM '/some_dir/some_file'

Solution

  • It is possible at least with PG 12.2:

    CREATE TABLE measurement (
        city_id         int not null,
        logdate         date not null,
        peaktemp        int,
        unitsales       int
    ) PARTITION BY RANGE (logdate);
    CREATE TABLE
    CREATE TABLE measurement_y2020m03 PARTITION OF measurement
        FOR VALUES FROM ('2020-03-01') TO ('2020-03-31');
    CREATE TABLE
    CREATE TABLE measurement_y2020m04 PARTITION OF measurement
        FOR VALUES FROM ('2020-04-01') TO ('2020-04-30');
    CREATE TABLE
    insert into measurement values (1, current_date, 10,100);
    INSERT 0 1
    select * from measurement;
     city_id |  logdate   | peaktemp | unitsales 
    ---------+------------+----------+-----------
           1 | 2020-03-27 |       10 |       100
    (1 row)
    
    cat /tmp/m.dat
    4,2020-04-01,40,400
    copy measurement_y2020m04 from '/tmp/m.dat' delimiter ',';
    COPY 1
    select * from measurement;
     city_id |  logdate   | peaktemp | unitsales 
    ---------+------------+----------+-----------
           1 | 2020-03-27 |       10 |       100
           4 | 2020-04-01 |       40 |       400
    (2 rows)