【问题标题】:How do I make the response from Python's requests package be a "file-like object"如何使 Python 请求包的响应成为“类文件对象”
【发布时间】: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


    【解决方案1】:

    您可以使用response.raw file object,但要考虑到任何内容编码(例如GZIP 或Deflate 压缩)仍然有效,除非您在调用.read() 时将decode_content 标志设置为True, psycopg2 不会。

    您可以在raw 文件对象上设置标志以将默认值更改为边读边解压缩:

    response.raw.decode_content = True
    

    然后使用response.raw文件对象到csv.DictReader()

    【讨论】:

    • 我没想过包装raw。太棒了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-10-31
    • 2016-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-26
    • 2019-10-19
    相关资源
    最近更新 更多