我使用copy_expert
中的psycopg2
方法将数据从CSV文件复制到postgresql表。我有这样的postgres表:
create table my_table (
cola text,
colb text,
colc text,
cold text,
cole text,
colf text,
colg text
)
包含类似前五列数据的CSV,如下所示:
cola,colb,colc,cold,cole
1,foo,a,10,vvv
2,bar,b,20,www
3,baz,c,30,xxx
4,boo,d,40,yyy
5,baa,e,50,zzz
我想复制前五列的CSV数据,同时还指定colf
和colg
的值(每行应具有colf
和{{的相同值1}})。
我可以将前五列复制到我的表中,如下所示:
colg
如何使用python指定最后两列的值?我知道我可以在表DDL中指定默认值,如下所示:
conn = psycopg2.connect('dbname=name user=username')
cur = conn.cursor()
copy_sql = """
copy my_table (cola, colb, colc, cold, cole)
from stdin with
csv
header
delimiter as ','
"""
from_csv = '/path/to/data.csv'
with open(from_csv, 'r') as f:
cur.copy_expert(sql=copy_sql, file=f)
conn.commit()
cur.close()
但是我想使用python添加值,因为每个CSV上传都有自己的create table my_table (
cola text,
colb text,
colc text,
cold text,
cole text,
colf text default 'foo',
colg text default 'bar'
)
和colf
值,这些值由我的python代码中的逻辑确定
答案 0 :(得分:1)
通过首先将我需要的列添加到数据中,然后上传更新的数据,看起来有几种方法可以做到这一点。
使用petl
包:
import psycopg2
from petl import fromcsv, addfield, todb
csv_file = '/path/to/data.csv'
table = fromcsv(csv_file)
table = addfield(table, 'colf', 'Some value')
table = addfield(table, 'colg', 'Another value')
conn = psycopg2.connect('dbname=test user=user')
todb(table, conn, 'my_table')
这在小数据上运行正常,但在大数据上却非常慢。 psycopg2
copy_from
和copy_expert
命令似乎更快,因为它们使用postgresql
批量复制。我首先将我的csv文件转换为copy_from
pandas
,然后使用dataframe
复制我的数据:
import psycopg2
import pandas as pd
from StringIO import StringIO
csv_file = '/path/to/file'
df = pd.read_csv(csv_file)
df['colf'] = 'My value'
df['colg'] = 'Foobar'
为了使用psycopg2
copy_
命令,我需要将dataframe
转换为具有read()
和readline()
的类似文件的对象方法,我可以使用StringIO
:
buf = StringIO()
df.to_csv(buf, header=False, index=False)
buf.pos = 0
请注意,您需要将缓冲区的pos
设置为0,因为pandas.to_csv
似乎默认将pos设置为结尾。有关说明,请参阅this SO answer。
然后我可以复制该缓冲区对象:
conn = psycopg2.connect('dbname=test user=user')
cur = conn.cursor()
cur.copy_from(buf, 'my_table', sep=',')
conn.commit()
cur.close()