Boto

2015-06-05 26 views
7

kullanarak S3'ten bir .gz dosyasını akışa alındığında sonsuz döngü Boto kullanarak S3'ten bir .gz dosyası akışı gerçekleştirmeye çalışıyorum ve sıkıştırılmamış metin dosyasının satırları üzerinde yineleyin. Gizemli bir şekilde döngü asla sona ermez; Tüm dosya okunduğunda, yineleme dosyanın başında yeniden başlatılır.Boto

ı oluşturmak demek ve benzeri bir giriş dosyası yüklemek edelim şu:

> echo '{"key": "value"}' > foo.json 
> gzip -9 foo.json 
> aws s3 cp foo.json.gz s3://my-bucket/my-location/ 

ve aşağıdaki Python komut dosyasını çalıştırın:

import boto 
import gzip 

connection = boto.connect_s3() 
bucket = connection.get_bucket('my-bucket') 
key = bucket.get_key('my-location/foo.json.gz') 
gz_file = gzip.GzipFile(fileobj=key, mode='rb') 
for line in gz_file: 
    print(line) 

sonucudur:

b'{"key": "value"}\n' 
b'{"key": "value"}\n' 
b'{"key": "value"}\n' 
...forever... 

Bu neden oluyor? Sanırım kayıp olduğum çok temel bir şey olmalı.

cevap

9

Ah, boto. Sorun şu ki, okuma metodu, anahtar bir kez tamamen okunduktan sonra çağırırsanız anahtarı yeniden indirir (farkı görmek için okuma ve sonraki yöntemleri karşılaştırın).

Bunu yapmanın en temiz yol değildir, ancak sorunu çözer:

import boto 
import gzip 

class ReadOnce(object): 
    def __init__(self, k): 
     self.key = k 
     self.has_read_once = False 

    def read(self, size=0): 
     if self.has_read_once: 
      return b'' 
     data = self.key.read(size) 
     if not data: 
      self.has_read_once = True 
     return data 

connection = boto.connect_s3() 
bucket = connection.get_bucket('my-bucket') 
key = ReadOnce(bucket.get_key('my-location/foo.json.gz')) 
gz_file = gzip.GzipFile(fileobj=key, mode='rb') 
for line in gz_file: 
    print(line) 
+0

+1: bu parlak. Aslında, sarıcınızı kullanarak, bir sıkıştırılmış S3 nesnesinden doğrudan bir DataFrame panda okuyabilirim. Teşekkürler! –

+0

Güzel! Bu, aynı zamanda, benim için de baştan sona birleştirilmiş dosya sonu gibi tuhaf davranışlar sergileyen CSV yüklemelerine de eşit derecede uygundu. Boto'nun bu gibi şeyleri neden yaptığını bilmek isterim - çok büyük hatalar IMO – killthrush

+0

Ayrıca bu çözümü bir içerik yöneticisi olarak çalıştırırken dikkat etmem de, bir 'kapat 'işlevini de uyguladım. Sadece self.key.close() 'ye 'kapat' deleğini verir. – killthrush

0

sayesinde harika içgörü ve excellent answer provided için zweiterlinde. Bir Pandalar DataFrame doğrudan sıkıştırılmış bir S3 nesnesi okumak için bir çözelti için ideal ve onun sarıcı kullanıyordu

, bu iki çizgi ile ifade edilebilir:

with gzip.GzipFile(fileobj=ReadOnce(bucket.get_key('my/obj.tsv.gz')), mode='rb') as f: 
    df = pd.read_csv(f, sep='\t') 
+1

Python, "en az satırda" kim "alabiliyor?", İncil'i okumaya devam et -> 'python -m this ' –

İlgili konular