How to copy from CSV file to PostgreSQL table with headers in CSV file?

前端 未结 5 1340
陌清茗
陌清茗 2020-12-04 08:51

I want to copy a CSV file to a Postgres table. There are about 100 columns in this table, so I do not want to rewrite them if I don\'t have to.

I am using the

5条回答
  •  青春惊慌失措
    2020-12-04 09:38

    I have been using this function for a while with no problems. You just need to provide the number columns there are in the csv file, and it will take the header names from the first row and create the table for you:

    create or replace function data.load_csv_file
        (
            target_table  text, -- name of the table that will be created
            csv_file_path text,
            col_count     integer
        )
    
        returns void
    
    as $$
    
    declare
        iter      integer; -- dummy integer to iterate columns with
        col       text; -- to keep column names in each iteration
        col_first text; -- first column name, e.g., top left corner on a csv file or spreadsheet
    
    begin
        set schema 'data';
    
        create table temp_table ();
    
        -- add just enough number of columns
        for iter in 1..col_count
        loop
            execute format ('alter table temp_table add column col_%s text;', iter);
        end loop;
    
        -- copy the data from csv file
        execute format ('copy temp_table from %L with delimiter '','' quote ''"'' csv ', csv_file_path);
    
        iter := 1;
        col_first := (select col_1
                      from temp_table
                      limit 1);
    
        -- update the column names based on the first row which has the column names
        for col in execute format ('select unnest(string_to_array(trim(temp_table::text, ''()''), '','')) from temp_table where col_1 = %L', col_first)
        loop
            execute format ('alter table temp_table rename column col_%s to %s', iter, col);
            iter := iter + 1;
        end loop;
    
        -- delete the columns row // using quote_ident or %I does not work here!?
        execute format ('delete from temp_table where %s = %L', col_first, col_first);
    
        -- change the temp table name to the name given as parameter, if not blank
        if length (target_table) > 0 then
            execute format ('alter table temp_table rename to %I', target_table);
        end if;
    end;
    
    $$ language plpgsql;
    

提交回复
热议问题