How to import CSV file data into a PostgreSQL table?

前端 未结 19 2308
再見小時候
再見小時候 2020-11-22 02:14

How can I write a stored procedure that imports data from a CSV file and populates the table?

19条回答
  •  长情又很酷
    2020-11-22 02:55

    Most other solutions here require that you create the table in advance/manually. This may not be practical in some cases (e.g., if you have a lot of columns in the destination table). So, the approach below may come handy.

    Providing the path and column count of your csv file, you can use the following function to load your table to a temp table that will be named as target_table:

    The top row is assumed to have the column names.

    create or replace function data.load_csv_file
    (
        target_table text,
        csv_path text,
        col_count integer
    )
    
    returns void as $$
    
    declare
    
    iter integer; -- dummy integer to iterate columns with
    col text; -- variable to keep the column name at each iteration
    col_first text; -- first column name, e.g., top left corner on a csv file or spreadsheet
    
    begin
        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_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
        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;
    

提交回复
热议问题