Можете ли вы загрузить на S3, используя поток, а не локальный файл?

Мне нужно создать CSV и загрузить его в ведро S3. Поскольку я создаю файл «на лету», было бы лучше, если бы я мог записать его непосредственно в ведро S3 по мере его создания, а не записывать весь файл локально, а затем загружать файл в конец.

Есть ли способ сделать это? Мой проект находится в Python, и я довольно новичок в этом языке. Вот что я пробовал до сих пор:

import csv import csv import io import boto from boto.s3.key import Key conn = boto.connect_s3() bucket = conn.get_bucket('dev-vs') k = Key(bucket) k.key = 'foo/foobar' fieldnames = ['first_name', 'last_name'] writer = csv.DictWriter(io.StringIO(), fieldnames=fieldnames) k.set_contents_from_stream(writer.writeheader()) 

Я получил эту ошибку: BotoClientError: s3 не поддерживает передачу каналов

UPDATE: я нашел способ напрямую писать на S3, но я не могу найти способ очистить буфер, фактически не удалив строки, которые я уже написал. Так, например:

 conn = boto.connect_s3() bucket = conn.get_bucket('dev-vs') k = Key(bucket) k.key = 'foo/foobar' testDict = [{ "fieldA": "8", "fieldB": None, "fieldC": "888888888888"}, { "fieldA": "9", "fieldB": None, "fieldC": "99999999999"}] f = io.StringIO() fieldnames = ['fieldA', 'fieldB', 'fieldC'] writer = csv.DictWriter(f, fieldnames=fieldnames) writer.writeheader() k.set_contents_from_string(f.getvalue()) for row in testDict: writer.writerow(row) k.set_contents_from_string(f.getvalue()) f.close() 

Записывает 3 строки в файл, однако я не могу освободить память для записи большого файла. Если я добавлю:

 f.seek(0) f.truncate(0) 

в цикле, тогда записывается только последняя строка файла. Есть ли способ освободить ресурсы, не удаляя строки из файла?

2 Solutions collect form web for “Можете ли вы загрузить на S3, используя поток, а не локальный файл?”

Я нашел решение своего вопроса, который я опубликую здесь, если кто-то еще интересуется. Я решил сделать это как часть в многостраничной загрузке. Вы не можете переходить на S3. Существует также пакет, который изменяет ваш потоковый файл на многостраничную загрузку, которую я использовал: Smart Open .

 import smart_open import io import csv testDict = [{ "fieldA": "8", "fieldB": None, "fieldC": "888888888888"}, { "fieldA": "9", "fieldB": None, "fieldC": "99999999999"}] fieldnames = ['fieldA', 'fieldB', 'fieldC'] f = io.StringIO() with smart_open.smart_open('s3://dev-test/bar/foo.csv', 'wb') as fout: writer = csv.DictWriter(f, fieldnames=fieldnames) writer.writeheader() fout.write(f.getvalue()) for row in testDict: f.seek(0) f.truncate(0) writer.writerow(row) fout.write(f.getvalue()) f.close() 

Согласно документам, это возможно

 s3.Object('mybucket', 'hello.txt').put(Body=open('/tmp/hello.txt', 'rb')) 

поэтому мы можем использовать StringIO обычным способом

  • Сравнение первых столбцов в двух файлах csv с использованием совпадений python и печати
  • Права доступа на уровне поля и Безопасность в openerp 7
  • Экспорт результатов ClearSoup в CSV; scrape + включить значения изображения в столбце
  • datetime dtypes в pandas read_csv
  • Загрузка файла в массив numpy с помощью python
  • Используя Matplotlib, визуализируйте данные CSV
  • Повторная выборка нескольких файлов CSV и автоматическое сохранение повторно выбранных файлов с новыми именами
  • как объединить 200 файлов csv в Python
  • Python - лучший язык программирования в мире.