如何编写从 CSV 文件导入数据并填充表的存储过程?
23 回答
看看这篇短文。
此处解释的解决方案:
创建你的表:
CREATE TABLE zip_codes
(ZIP char(5), LATITUDE double precision, LONGITUDE double precision,
CITY varchar, STATE char(2), COUNTY varchar, ZIP_CLASS varchar);
将数据从 CSV 文件复制到表中:
COPY zip_codes FROM '/path/to/csv/ZIP_CODES.txt' WITH (FORMAT csv);
如果您没有使用权限COPY
(在 db 服务器上工作),您可以\copy
改用(在 db 客户端上工作)。使用与 Bozhidar Batsov 相同的示例:
创建你的表:
CREATE TABLE zip_codes
(ZIP char(5), LATITUDE double precision, LONGITUDE double precision,
CITY varchar, STATE char(2), COUNTY varchar, ZIP_CLASS varchar);
将数据从 CSV 文件复制到表中:
\copy zip_codes FROM '/path/to/csv/ZIP_CODES.txt' DELIMITER ',' CSV
请注意 \copy ... 必须写在一行中并且没有 ; 在最后!
您还可以指定要读取的列:
\copy zip_codes(ZIP,CITY,STATE) FROM '/path/to/csv/ZIP_CODES.txt' DELIMITER ',' CSV
请参阅COPY 的文档:
不要将 COPY 与 psql 指令 \copy 混淆。\copy 调用 COPY FROM STDIN 或 COPY TO STDOUT,然后在 psql 客户端可访问的文件中获取/存储数据。因此,当使用 \copy 时,文件可访问性和访问权限取决于客户端而不是服务器。
并注意:
对于标识列,COPY FROM 命令将始终写入输入数据中提供的列值,例如 INSERT 选项 OVERRIDING SYSTEM VALUE。
一种快速的方法是使用 Python pandas 库(0.15 或更高版本效果最好)。这将为您处理创建列 - 尽管显然它为数据类型所做的选择可能不是您想要的。如果它不能完全满足您的要求,您始终可以使用作为模板生成的“创建表”代码。
这是一个简单的例子:
import pandas as pd
df = pd.read_csv('mypath.csv')
df.columns = [c.lower() for c in df.columns] #postgres doesn't like capitals or spaces
from sqlalchemy import create_engine
engine = create_engine('postgresql://username:password@localhost:5432/dbname')
df.to_sql("my_table_name", engine)
下面是一些代码,向您展示如何设置各种选项:
# Set it so the raw sql output is logged
import logging
logging.basicConfig()
logging.getLogger('sqlalchemy.engine').setLevel(logging.INFO)
df.to_sql("my_table_name2",
engine,
if_exists="append", #options are ‘fail’, ‘replace’, ‘append’, default ‘fail’
index=False, #Do not output the index of the dataframe
dtype={'col1': sqlalchemy.types.NUMERIC,
'col2': sqlalchemy.types.String}) #Datatypes should be [sqlalchemy types][1]
这里的大多数其他解决方案都要求您提前/手动创建表。这在某些情况下可能不切实际(例如,如果目标表中有很多列)。因此,下面的方法可能会派上用场。
提供 csv 文件的路径和列数,您可以使用以下函数将表加载到临时表,该表将命名为target_table
:
假定顶行具有列名。
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;
您还可以使用 pgAdmin,它提供了一个 GUI 来进行导入。这显示在这个SO 线程中。使用 pgAdmin 的优点是它也适用于远程数据库。
不过,与之前的解决方案非常相似,您需要已经将表放在数据库中。每个人都有自己的解决方案,但我通常做的是在 Excel 中打开 CSV,复制标题,在不同的工作表上进行特殊粘贴,将相应的数据类型放在下一列,然后将其复制并粘贴到文本编辑器连同适当的 SQL 表创建查询,如下所示:
CREATE TABLE my_table (
/*paste data from Excel here for example ... */
col_1 bigint,
col_2 bigint,
/* ... */
col_n bigint
)
COPY table_name FROM 'path/to/data.csv' DELIMITER ',' CSV HEADER;
先建一个表
然后使用 copy 命令复制表的详细信息:
复制table_name (C1,C2,C3....)
从“你的 csv 文件的路径”分隔符 ',' csv 标头;
谢谢
使用此 SQL 代码
copy table_name(atribute1,attribute2,attribute3...)
from 'E:\test.csv' delimiter ',' csv header
header 关键字让 DBMS 知道 csv 文件有一个带有属性的标题
更多信息请访问http://www.postgresqltutorial.com/import-csv-file-into-posgresql-table/
个人使用PostgreSQL的经验,还在等待更快的方法。
1.如果文件存储在本地,首先创建表骨架:
drop table if exists ur_table;
CREATE TABLE ur_table
(
id serial NOT NULL,
log_id numeric,
proc_code numeric,
date timestamp,
qty int,
name varchar,
price money
);
COPY
ur_table(id, log_id, proc_code, date, qty, name, price)
FROM '\path\xxx.csv' DELIMITER ',' CSV HEADER;
2.当\path\xxx.csv在服务器上时,postgreSQL没有访问服务器的权限,需要通过pgAdmin内置功能导入.csv文件。
右键单击表名选择导入。
如果仍有问题,请参考本教程。 http://www.postgresqltutorial.com/import-csv-file-into-posgresql-table/
如何将 CSV 文件数据导入 PostgreSQL 表?
脚步:
需要在终端连接postgresql数据库
psql -U postgres -h localhost
需要创建数据库
create database mydb;
需要创建用户
create user siva with password 'mypass';
连接数据库
\c mydb;
需要创建架构
create schema trip;
需要建表
create table trip.test(VendorID int,passenger_count int,trip_distance decimal,RatecodeID int,store_and_fwd_flag varchar,PULocationID int,DOLocationID int,payment_type decimal,fare_amount decimal,extra decimal,mta_tax decimal,tip_amount decimal,tolls_amount int,improvement_surcharge decimal,total_amount );
将csv文件数据导入postgresql
COPY trip.test(VendorID int,passenger_count int,trip_distance decimal,RatecodeID int,store_and_fwd_flag varchar,PULocationID int,DOLocationID int,payment_type decimal,fare_amount decimal,extra decimal,mta_tax decimal,tip_amount decimal,tolls_amount int,improvement_surcharge decimal,total_amount) FROM '/home/Documents/trip.csv' DELIMITER ',' CSV HEADER;
查找给定的表数据
select * from trip.test;
恕我直言,最方便的方法是遵循“将CSV 数据导入 postgresql,舒适的方式 ;-) ”,使用csvkit中的csvsql,这是一个可通过 pip 安装的 python 包。
在 Python 中,您可以使用此代码使用列名自动创建 PostgreSQL 表:
import pandas, csv
from io import StringIO
from sqlalchemy import create_engine
def psql_insert_copy(table, conn, keys, data_iter):
dbapi_conn = conn.connection
with dbapi_conn.cursor() as cur:
s_buf = StringIO()
writer = csv.writer(s_buf)
writer.writerows(data_iter)
s_buf.seek(0)
columns = ', '.join('"{}"'.format(k) for k in keys)
if table.schema:
table_name = '{}.{}'.format(table.schema, table.name)
else:
table_name = table.name
sql = 'COPY {} ({}) FROM STDIN WITH CSV'.format(table_name, columns)
cur.copy_expert(sql=sql, file=s_buf)
engine = create_engine('postgresql://user:password@localhost:5432/my_db')
df = pandas.read_csv("my.csv")
df.to_sql('my_table', engine, schema='my_schema', method=psql_insert_copy)
它也比较快,我可以在大约 4 分钟内导入超过 330 万行。
如果文件非常大,您可以使用 pandas 库。在 pandas 数据帧上使用 iter 时要小心。我在这里这样做是为了证明这种可能性。从数据框复制到 sql 表时,还可以考虑使用 pd.Dataframe.to_sql() 函数
假设您已经创建了您想要的表,您可以:
import psycopg2
import pandas as pd
data=pd.read_csv(r'path\to\file.csv', delimiter=' ')
#prepare your data and keep only relevant columns
data.drop(['col2', 'col4','col5'], axis=1, inplace=True)
data.dropna(inplace=True)
print(data.iloc[:3])
conn=psycopg2.connect("dbname=db user=postgres password=password")
cur=conn.cursor()
for index,row in data.iterrows():
cur.execute('''insert into table (col1,col3,col6)
VALUES (%s,%s,%s)''', (row['col1'], row['col3'], row['col6'])
cur.close()
conn.commit()
conn.close()
print('\n db connection closed.')
我创建了一个小工具,将csv
文件导入 PostgreSQL 超级简单,只需一个命令,它就会创建和填充表,不幸的是,目前自动创建的所有字段都使用 TEXT 类型
csv2pg users.csv -d ";" -H 192.168.99.100 -U postgres -B mydatabase
如果您需要从文本/解析多行 CSV 导入的简单机制,您可以使用:
CREATE TABLE t -- OR INSERT INTO tab(col_names)
AS
SELECT
t.f[1] AS col1
,t.f[2]::int AS col2
,t.f[3]::date AS col3
,t.f[4] AS col4
FROM (
SELECT regexp_split_to_array(l, ',') AS f
FROM regexp_split_to_table(
$$a,1,2016-01-01,bbb
c,2,2018-01-01,ddd
e,3,2019-01-01,eee$$, '\n') AS l) t;
创建表并具有用于在 csv 文件中创建表的所需列。
打开 postgres 并右键单击要加载的目标表并选择导入并更新文件选项部分中的以下步骤
现在在文件名中浏览您的文件
选择csv格式
编码为 ISO_8859_5
现在转到杂项。选项并检查标题并单击导入。
您可以将 bash 文件创建为 import.sh(您的 CSV 格式是制表符分隔符)
#!/usr/bin/env bash
USER="test"
DB="postgres"
TBALE_NAME="user"
CSV_DIR="$(pwd)/csv"
FILE_NAME="user.txt"
echo $(psql -d $DB -U $USER -c "\copy $TBALE_NAME from '$CSV_DIR/$FILE_NAME' DELIMITER E'\t' csv" 2>&1 |tee /dev/tty)
然后运行这个脚本。
您有 3 个选项将 CSV 文件导入 PostgreSQL:首先,通过命令行使用 COPY 命令。
其次,使用 pgAdmin 工具的导入/导出。
第三,使用像 Skyvia 这样的云解决方案,它可以从在线位置(如 FTP 源)或云存储(如 Google Drive)获取 CSV 文件。
您可以从这里查看解释所有这些的文章。
DBeaver 社区版 (dbeaver.io) 使连接数据库变得简单,然后导入 CSV 文件以上传到 PostgreSQL 数据库。它还可以轻松发出查询、检索数据以及将结果集下载为 CSV、JSON、SQL 或其他常见数据格式。
它是一款面向 SQL 程序员、DBA 和分析师的 FOSS 多平台数据库工具,支持所有流行的数据库:MySQL、PostgreSQL、SQLite、Oracle、DB2、SQL Server、Sybase、MS Access、Teradata、Firebird、Hive、Presto 等。它是 TOAD for Postgres、TOAD for SQL Server 或 Toad for Oracle 的可行 FOSS 竞争对手。
我与 DBeaver 没有任何关系。我喜欢它的价格(免费!)和完整的功能,但我希望他们能更多地打开这个 DBeaver/Eclipse 应用程序,让向 DBeaver/Eclipse 添加分析小部件变得容易,而不是要求用户支付 199 美元的年度订阅费直接在应用程序中创建图形和图表。我的 Java 编码技能生疏了,我不想花几周时间重新学习如何构建 Eclipse 小部件(只是发现 DBeaver 可能已经禁用了将第三方小部件添加到 DBeaver 社区版的功能。)
作为 Java 开发人员的 DBeaver 高级用户能否提供一些有关创建分析小部件以添加到 DBeaver 社区版的步骤的见解?
我的想法是将您的 CSV 转换为 SQL 查询,希望对您有所帮助。
- 打开工具Convert CSV to Insert SQL Online
Data Source
在窗格中粘贴或上传您的 CSV 文件- 滚动到
Table Generator
面板 - 点击
Copy to clipboard
或Download
例子:
id,name
1,Roberta
2,Oliver
SQL 查询的输出:
CREATE TABLE tableName
(
id varchar(300),
name varchar(300)
);
INSERT INTO tableName (id,name)
VALUES
('1', 'Roberta'),
('2', 'Oliver');