首页 文章

我可以从带有 Headers 的csv文件中自动在PostgreSQL中创建一个表吗?

提问于
浏览
34

我在OS X 10.6.8上运行PostgreSQL 9.2.6 . 我想将带有列 Headers 的CSV文件中的数据导入数据库 . 我可以使用 COPY 语句执行此操作,但前提是我首先手动创建一个包含CSV文件中每列的列的表 . 有没有办法根据CSV文件中的 Headers 自动创建此表?

this question我试过了

COPY test FROM '/path/to/test.csv' CSV HEADER;

但我只是得到这个错误:

ERROR: relation "test" does not exist

如果我首先创建一个没有列的表:

CREATE TABLE test ();

我明白了:

ERROR: extra data after last expected column

关于自动创建表,我在PostgreSQL _1734362中找不到任何内容 . 是否有其他方法可以自动从带有 Headers 的CSV文件创建表格?

3 回答

  • 12

    您无法在COPY文档中找到任何内容,因为COPY cannot 会为您创建一个表格 .
    你需要先做到这一点,然后才能做到这一点 .

  • 26

    有一个非常好的工具可以从csv文件中将表导入Postgres . 它是一个名为pgfutter(with binaries for windows, linux, etc.)的命令行工具 . 它的一大优点是它也能识别属性/列名 .

    该工具的使用很简单 . 例如,如果您要导入 myCSVfile.csv

    pgfutter --db "myDatabase" --port "5432" --user "postgres" --pw "mySecretPassword" csv myCSVfile.csv
    

    这将创建一个表(称为 myCSVfile ),其列名取自csv文件的 Headers . 此外,将从现有数据中识别数据类型 .

    一些注意事项:命令 pgfutter 根据您使用的二进制文件而有所不同,例如:它可能是 pgfutter_windows_amd64.exe (如果您打算经常使用此命令,请将其重命名) . 上述命令必须在命令行窗口中执行(例如,在Windows中运行 cmd 并确保可以访问 pgfutter ) . 如果您想要一个不同的表名,请添加 --table "myTable" ;选择一个特定的数据库模式 --schema "mySchema" . 如果您正在访问外部数据库,请使用 --host "myHostDomain" .

    pgfuttermyFile 导入 myTable 的更详细的例子是这一个:

    pgfutter --host "localhost" --port "5432" --db "myDB" --schema "public" --table "myTable" --user "postgres" --pw "myPwd" csv myFile.csv
    

    最有可能在导入后您将更改一些数据类型(从文本到数字):

    alter table myTable
      alter column myColumn type numeric
        using (trim(myColumn)::numeric)
    
  • 20

    还有第二种方法,我找到了here(来自mmatt) . 基本上你在Postgres中调用一个函数(最后一个参数指定列数) .

    select load_csv_file('myTable','C:/MyPath/MyFile.csv',24)
    

    这是mmatt的功能代码,我不得不稍微修改,因为我正在处理公共模式 . (复制并粘贴到PgAdmin SQL编辑器并运行它以创建函数)

    CREATE OR REPLACE FUNCTION load_csv_file(
        target_table text,
        csv_path text,
        col_count integer)
      RETURNS void AS
    $BODY$
    
    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
        set schema 'public';
    
        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;
    
    $BODY$
      LANGUAGE plpgsql VOLATILE
      COST 100;
    ALTER FUNCTION load_csv_file(text, text, integer)
      OWNER TO postgres;
    

    注意:导入与编码相关的文本文件存在一个常见问题 . csv文件应为UTF-8格式 . 但是,有时候尝试进行编码的程序并没有完全实现这一点 . 我通过在记事本中打开文件并将其转换为ANSI并返回到UTF8来克服此问题 .

相关问题