簡體   English   中英

如何使 Python 的請求包的響應成為“類文件對象”

[英]How do I make the response from Python's requests package be a “file-like object”

我正在使用 Python 的requests庫訪問網絡服務,並且端點正在返回一個(非常大的)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()

我得到的錯誤是:

文件必須是 COPY FROM 的可讀文件類對象; 用於 COPY TO 的可寫類文件對象。

我明白錯誤在說什么; 事實上,我可以從psycopg2 文檔中看到copy_expert調用copy_from ,其中:

從類似文件的對象中讀取數據,並將它們附加到數據庫表中(COPY table FROM file 語法)。 源文件必須同時具有 read() 和 readline() 方法。

我的問題是我找不到使response對象成為類文件對象的方法! 我嘗試了.data.iter_lines沒有成功。 我當然不想從網絡服務下載整個數千兆字節的文件,然后將其上傳到 RedShift。 必須有一種方法可以將流響應用作類似文件的對象,psycopg2 可以將其復制到 RedShift 中。 有誰知道我錯過了什么?

您可以使用response.raw文件對象,但要考慮到任何內容編碼(例如 GZIP 或 Deflate 壓縮)仍然存在,除非您在調用.read()時將decode_content標志設置為True ,而 psycopg2 不會.

您可以在raw文件對象上設置標志以將默認值更改為 decompressing-while-reading:

response.raw.decode_content = True

然后將response.raw文件對象用於csv.DictReader()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM