多记录上传到postgres

时间:2016-10-31 19:38:24

标签: python postgresql

我有一系列带有一些数据的.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查询仍然没有在表中显示任何记录。我错过了什么?

编辑:我最终放弃并将其写入临时文件,然后上传文件。这没有任何麻烦...我显然宁愿没有临时文件,所以如果有人看到问题我很乐意有建议。

1 个答案:

答案 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中的所有行。

不要忘记,您读取并保留了内存中的所有文件,这些文件可能只适用于一次小型导入,但在并行执行大型导入或多次导入时可能会成为问题。