我可以从带有标题的csv文件中自动在PostgreSQL中创建一个表吗?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了我可以从带有标题的csv文件中自动在PostgreSQL中创建一个表吗?相关的知识,希望对你有一定的参考价值。
我在OS X 10.6.8上运行PostgreSQL 9.2.6。我想将带有列标题的CSV文件中的数据导入数据库。我可以使用COPY
语句执行此操作,但前提是我首先手动创建一个包含CSV文件中每列的列的表。有没有办法根据CSV文件中的标题自动创建此表?
每个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 COPY documentation中找不到关于自动创建表的任何内容。是否有其他方法可以自动从带有标题的CSV文件创建表格?
您在COPY
文档中找不到任何内容,因为COPY无法为您创建表格。
你需要在COPY
之前做到这一点。
有一个非常好的工具可以从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文件的标题。此外,将从现有数据中识别数据类型。
一些注意事项:命令pgfutter
根据您使用的二进制文件而有所不同,例如:它可能是pgfutter_windows_amd64.exe
(如果你打算经常使用这个命令,重命名它)。上述命令必须在命令行窗口中执行(例如在Windows中运行cmd
并确保可以访问pgfutter
)。如果您想要一个不同的表名,请添加--table "myTable"
;选择一个特定的数据库模式我们--schema "mySchema"
。如果您正在访问外部数据库,请使用--host "myHostDomain"
。
将pgfutter
导入myFile
的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)
还有第二种方法,我找到了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格式。但是,有时候尝试进行编码的程序并没有完全实现这一点。我通过在Notepad ++中打开文件并将其转换为ANSI并返回到UTF8来克服此问题。
以上是关于我可以从带有标题的csv文件中自动在PostgreSQL中创建一个表吗?的主要内容,如果未能解决你的问题,请参考以下文章
BigQuery - 通过应用脚本上传带有模式自动检测的 csv