Потоковая передача данных из облачного хранилища Google на FTP-сервер - PullRequest
1 голос
/ 11 ноября 2019

Я пытаюсь использовать gcsfs и ftplib для передачи CSV по линиям / частям из облачного хранилища на FTP-сервер. У меня есть большие файлы в GCS, которые я не могу сохранить в памяти, поэтому я пытаюсь протестировать этот способ.

from ftplib import FTP
import gcsfs
from urllib import request
import io

ftp = FTP('my-ftp-server')

fs = gcsfs.GCSFileSystem(project='my-project')

with fs.open('myFile.csv') as f:
    ftp.storlines("STOR myFile.csv", f)

, но я получаю ошибку:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-56-d461792392dd> in <module>
      1 with fs.open('myfile') as f:
----> 2     ftp.storlines("STOR myFile.csv", f)

~\.conda\envs\py3.7\lib\ftplib.py in storlines(self, cmd, fp, callback)
    530         with self.transfercmd(cmd) as conn:
    531             while 1:
--> 532                 buf = fp.readline(self.maxline + 1)
    533                 if len(buf) > self.maxline:
    534                     raise Error("got more than %d bytes" % self.maxline)

TypeError: readline() takes 1 positional argument but 2 were given

Любые предложенияо том, как я могу это исправить или добиться того, что я хочу?

1 Ответ

1 голос
/ 11 ноября 2019

Действительно, fsspec.AbstractFileSystem (на котором основан GCSFileSystem), в частности его readline метод , похоже, не совместим с ftplib.


Вам нужно использовать FTP.storlines (текстовый режим)? Не можете ли вы использовать FTP.storbinary (двоичный режим)?

with fs.open('myFile.csv') as f:
    ftp.storbinary("STOR myFile.csv", f)

FTP.storbinary передает файл порциями (определяется необязательным параметром blocksize со значением по умолчанию 8192).


Если нет, вам придется реализовать класс-оболочку с API, совместимым с FTP.storlines:

class GCSFileSystemCompat:

    def __init__(self, f):
        self.f = f

    def readline(self, size):
        return f.readline()

with fs.open('myFile.csv') as f,
    ftp.storlines("STOR myFile.csv", GCSFileSystemCompat(f))

(не проверено, но оно должно датьвам идея)

...