如何编写从CSV文件导入数据并填充表的存储过程?
当前回答
COPY table_name FROM 'path/to/data.csv' DELIMITER ',' CSV HEADER;
其他回答
正如Paul提到的,导入在pgAdmin中起作用:
右键单击表→导入
选择一个本地文件,格式和编码。
这是一个德文pgAdmin GUI截图:
使用DbVisualizer也可以做类似的事情(我有许可证,但不确定是否有免费版本)。
右键单击表→导入表数据…
这里的大多数其他解决方案都要求您提前/手动创建表。这在某些情况下可能不实用(例如,如果目标表中有很多列)。因此,下面的方法可能会派上用场。
提供你的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;
如果文件不是很大,可以使用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.')
在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多万行。
首先创建一个表 然后使用copy命令复制表的详细信息: 复制table_name (C1,C2,C3....) 从'路径到您的CSV文件'分隔符,' CSV头;
注意:
列和顺序由C1,C2,C3..在SQL 标题选项只是从输入中跳过一行,而不是根据列的名称。
推荐文章
- django test app error -在创建测试数据库时出现错误:创建数据库的权限被拒绝
- Postgres唯一约束与索引
- 使用电子邮件地址为主键?
- 选择postgres中字段的数据类型
- 如何在PostgreSQL中查看视图的CREATE VIEW代码?
- 错误:没有唯一的约束匹配给定的键引用表"bar"
- 如何使用新的PostgreSQL JSON数据类型中的字段进行查询?
- 如何彻底清除和重新安装postgresql在ubuntu?
- 分组限制在PostgreSQL:显示每组的前N行?
- IN与PostgreSQL中的ANY运算符
- PSQLException:当前事务被中止,命令被忽略,直到事务块结束
- 添加布尔列到表集默认
- 库未加载:/usr/local/opt/readline/lib/libreadline.6.2.dylib
- 如何将这个字典列表转换为csv文件?
- Python导入csv到列表