Как использовать Paramiko getfo для загрузки файла с SFTP-сервера в память для его обработки - PullRequest
0 голосов
/ 25 мая 2018

Я пытаюсь загрузить CSV-файл (в памяти) из SFTP с помощью Paramiko и импортировать его в файл данных pandas.

transport = paramiko.Transport((server, 22))
transport.connect(username=username, password=password)
sftp = paramiko.SFTPClient.from_transport(transport)

with open(file_name, 'wb') as fl:
    sftp.getfo(file_name, fl, callback=printTotals)
    df = pd.read_csv(fl, sep=' ')

Приведенный ниже код завершается ошибкой, сообщая мне:

OSError: Файл не открыт для чтения

Я предполагаю, что вместо fl мне нужен какой-то буфер или объект типа файла, так как для открытия нужен файл.Я относительно новичок во всем этом, поэтому я был бы рад, если бы кто-то мог помочь.

Ответы [ 2 ]

0 голосов
/ 28 мая 2018

То, что я закончил, было простой версией этого, к сожалению, без обратного вызова для прогресса, мне также нужно было rb для чтения:

with sftp.open(file_name, 'rb') as fl:
        df = pd.read_csv(fl, sep=' ')

В любом случае, ответ Мартина - то, что я искалдля!

0 голосов
/ 28 мая 2018

Простое решение, которое все еще позволяет вам использовать обратный вызов прогресса:

  • Использование BytesIO файлоподобного объекта для сохранения загруженного файла в память;
  • Вы должны искать указатель файла обратно к началу файла после его загрузки, прежде чем начать его чтение.
with io.BytesIO() as fl:
    sftp.getfo(file_name, fl, callback=printTotals)
    fl.seek(0)
    df = pd.read_csv(fl, sep=' ')

Хотя с этим решением вы в конечном итоге загрузите файл в памятьдважды.


Лучшее решение - реализовать объект, подобный файлу.Это даже позволит вам загружать и анализировать файл одновременно.

class FileWithProgress:

    def __init__(self, fl):
        self.fl = fl
        self.size = fl.stat().st_size
        self.p = 0

    def read(self, blocksize):
        r = self.fl.read(blocksize)
        self.p += len(r)
        print(str(self.p) + " of " + str(self.size)) 
        return r

И использовать его как:

with sftp.open(file_name, "rb") as fl:
    fl.prefetch()
    df = pd.read_csv(FileWithProgress(fl), sep=' ') 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...