Si encuentras alguna parte que no entiendes puedes dejarlo en la sección de comentarios y haremos todo lo necesario de ayudarte lo más rápido posible.
Solución:
Una solución simple que aún le permite usar la devolución de llamada de progreso es:
-
Utilizar
BytesIO
objeto similar a un archivo para almacenar un archivo descargado en la memoria; -
Debe buscar el puntero del archivo para volver al inicio del archivo después de descargarlo, antes de comenzar a leerlo.
with io.BytesIO() as fl: sftp.getfo(file_name, fl, callback=printTotals) fl.seek(0) df = pd.read_csv(fl, sep=' ')
Aunque con esta solución, terminará cargando el archivo en la memoria dos veces.
La mejor solución es implementar un objeto similar a un archivo personalizado. Incluso le permitirá descargar y analizar el archivo al mismo tiempo.
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
Y usarlo como:
with sftp.open(file_name, "rb") as fl:
fl.prefetch()
df = pd.read_csv(FileWithProgress(fl), sep=' ')
Para el SFTPFile.prefetch
llame, consulte:
La lectura del archivo abierto con el método Python Paramiko SFTPClient.open es lenta.
Lo que terminé haciendo fue una versión simple de eso, desafortunadamente sin una devolución de llamada para el progreso, también necesitaba rb
para leer:
with sftp.open(file_name, 'rb') as fl:
df = pd.read_csv(fl, sep=' ')
De todos modos, ¡la respuesta de Martin es lo que estaba buscando!
Si entiendes que te ha sido provechoso este artículo, sería de mucha ayuda si lo compartes con otros juniors de este modo contrubuyes a extender nuestra información.