2014-07-17 21 views
3

我正在用Python的requests庫打擊web服務,並且端點正在返回一個(非常大的)CSV文件,然後我想將它們流入數據庫。代碼如下所示:我如何使Python的請求包中的響應成爲「類文件對象」

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的亞馬遜紅移,這是我已經可以使用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從可讀的文件對象;用於COPY TO的可寫文件類對象。

我明白錯誤在說什麼;

從他們追加到數據庫表(COPY FROM表文件語法)一個類文件對象中讀取數據:其實,我可以從psycopg2 documentationcopy_expert電話copy_from,內見。源文件必須同時具有read()和readline()方法。

我的問題是,我找不到一種方法來使response對象成爲一個文件類對象!我嘗試了.data.iter_lines都沒有成功。我當然不希望從web服務下載整個多GB文件,然後將其上傳到RedShift。必須有一種方法可以將流式響應用作psycopg2可以複製到RedShift中的類文件對象。任何人都知道我錯過了什麼?

回答

3

除非你打電話.read()時,這psycopg2將不設置decode_content標誌True你可以使用response.raw file object,但考慮到任何內容編碼(如gzip或deflate壓縮)仍然會到位。

您可以設置標誌raw文件對象,就可以改變默認解壓,而閱讀:

response.raw.decode_content = True 

,然後使用response.raw文件對象csv.DictReader()

+0

我沒有考慮包裝'生'。輝煌。 –

相關問題