我有一系列带有一些数据的.csv文件,我想要一个Python脚本打开它们,做一些预处理,并将处理过的数据上传到我的postgres数据库。
我大部分都已完成,但我的上传步骤无效。我确信这很简单,我很想念,但我找不到它。我很感激您提供的任何帮助。
以下是代码:
import psycopg2
import sys
from os import listdir
from os.path import isfile, join
import csv
import re
import io
try:
con = db_connect("dbname = '[redacted]' user = '[redacted]' password = '[redacted]' host = '[redacted]'")
except:
print("Can't connect to database.")
sys.exit(1)
cur = con.cursor()
upload_file = io.StringIO()
file_list = [f for f in listdir(mypath) if isfile(join(mypath, f))]
for file in file_list:
id_match = re.search(r'.*-(\d+)\.csv', file)
if id_match:
id = id_match.group(1)
file_name = format(id_match.group())
with open(mypath+file_name) as fh:
id_reader = csv.reader(fh)
next(id_reader, None) # Skip the header row
for row in id_reader:
[stuff goes here to get desired values from file]
if upload_file.getvalue() != '': upload_file.write('\n')
upload_file.write('{0}\t{1}\t{2}'.format(id, [val1], [val2]))
print(upload_file.getvalue()) # prints output that looks like I expect it to
# with thousands of rows that seem to have the right values in the right fields
cur.copy_from(upload_file, '[my_table]', sep='\t', columns=('id', 'col_1', 'col_2'))
con.commit()
if con:
con.close()
这样运行没有错误,但psql中的select查询仍然没有在表中显示任何记录。我错过了什么?
编辑:我最终放弃并将其写入临时文件,然后上传文件。这没有任何麻烦...我显然宁愿没有临时文件,所以如果有人看到问题我很乐意有建议。
答案 0 :(得分:1)
当您写入io.StringIO
(或任何其他文件)对象时,文件指针仍保留在写入的最后一个字符的位置。所以,当你做的时候
f = io.StringIO()
f.write('1\t2\t3\n')
s = f.readline()
文件指针停留在文件末尾,s
包含空字符串。
要读取(不是getvalue
)内容,您必须将文件指针重新定位到开头,例如使用seek(0)
upload_file.seek(0)
cur.copy_from(upload_file, '[my_table]', columns = ('id', 'col_1', 'col_2'))
这允许copy_from
从头开始阅读并导入upload_file
中的所有行。
不要忘记,您读取并保留了内存中的所有文件,这些文件可能只适用于一次小型导入,但在并行执行大型导入或多次导入时可能会成为问题。