【发布时间】:2014-09-08 00:55:32
【问题描述】:
我正在使用 Python 的 requests 库访问 Web 服务,并且端点正在返回一个(非常大的)CSV 文件,然后我想将其流式传输到数据库中。代码如下所示:
response = requests.get(url, auth=auth, stream=True)
if response.status_code == 200:
stream_csv_into_database(response)
现在,当数据库是 MongoDB 数据库时,使用 DictReader 可以完美加载:
def stream_csv_into_database(response):
.
.
.
for record in csv.DictReader(response.iter_lines(), delimiter='\t'):
product_count += 1
product = {k:v for (k,v) in record.iteritems() if v}
product['_id'] = product_count
collection.insert(product)
但是,我正在从 MongoDB 切换到 Amazon RedShift,我已经可以使用 psycopg2 很好地访问它。我可以打开连接并进行简单的查询,但我想做的是使用来自 web 服务的流式响应并使用 psycopg2 的copy_expert 加载 RedShift 表。到目前为止,这是我尝试过的:
def stream_csv_into_database(response, campaign, config):
print 'Loading product feed for {0}'.format(campaign)
conn = new_redshift_connection(config) # My own helper, works fine.
table = 'products.' + campaign
cur = conn.cursor()
reader = response.iter_lines()
# Error on following line:
cur.copy_expert("COPY {0} FROM STDIN WITH CSV HEADER DELIMITER '\t'".format(table), reader)
conn.commit()
cur.close()
conn.close()
我得到的错误是:
file 必须是 COPY FROM 的可读文件类对象; COPY TO 的可写文件类对象。
我明白错误在说什么;事实上,我可以从psycopg2 documentation 中看到copy_expert 调用copy_from,其中:
从类似文件的对象中读取数据,并将它们附加到数据库表(COPY table FROM file 语法)。源文件必须同时具有 read() 和 readline() 方法。
我的问题是我找不到使response 对象成为类文件对象的方法!我尝试了.data 和.iter_lines 都没有成功。我当然不想从 web 服务下载整个数千兆字节的文件,然后将其上传到 RedShift。必须有一种方法可以将流响应用作 psycopg2 可以复制到 RedShift 中的类文件对象。有人知道我错过了什么吗?
【问题讨论】:
标签: python python-requests psycopg2 amazon-redshift