J'essaie d'enregistrer des fichiers volumineux depuis le Blobstore de Google App Engine vers Google Cloud Storage pour faciliter la sauvegarde.
Cela fonctionne bien pour les petits fichiers (<10 mb) mais pour les fichiers plus importants, cela devient instable et GAE lance une erreur FileNotOpenedError.
Mon code :
PATH = '/gs/backupbucket/'
for df in DocumentFile.all():
fn = df.blob.filename
br = blobstore.BlobReader(df.blob)
write_path = files.gs.create(self.PATH+fn.encode('utf-8'), mime_type='application/zip',acl='project-private')
with files.open(write_path, 'a') as fp:
while True:
buf = br.read(100000)
if buf=="": break
fp.write(buf)
files.finalize(write_path)
(Exécute dans un taskeque pour éviter de dépasser le temps d'exécution).
Lance une erreur FileNotOpenedError :
Traceback (most recent call last):
File "/base/python27\_runtime/python27\_lib/versions/third\_party/webapp2-2.3/webapp2.py", line 1511, in \_\_call\_\_
rv = self.handle\_exception(request, response, e)
File "/base/python27\_runtime/python27\_lib/versions/third\_party/webapp2-2.3/webapp2.py", line 1505, in \_\_call\_\_
rv = self.router.dispatch(request, response)
File "/base/python27\_runtime/python27\_lib/versions/third\_party/webapp2-2.3/webapp2.py", line 1253, in default\_dispatcher
return route.handler\_adapter(request, response)
File "/base/python27\_runtime/python27\_lib/versions/third\_party/webapp2-2.3/webapp2.py", line 1077, in \_\_call\_\_
return handler.dispatch()
File "/base/python27\_runtime/python27\_lib/versions/third\_party/webapp2-2.3/webapp2.py", line 547, in dispatch
return self.handle\_exception(e, self.app.debug)
File "/base/python27\_runtime/python27\_lib/versions/third\_party/webapp2-2.3/webapp2.py", line 545, in dispatch
return method(\*args, \*\*kwargs)
File "/base/data/home/apps/s~simplerepository/1.354754771592783168/processFiles.py", line 249, in post
fp.write(buf)
File "/base/python27\_runtime/python27\_lib/versions/1/google/appengine/api/files/file.py", line 281, in \_\_exit\_\_
self.close()
File "/base/python27\_runtime/python27\_lib/versions/1/google/appengine/api/files/file.py", line 275, in close
self.\_make\_rpc\_call\_with\_retry('Close', request, response)
File "/base/python27\_runtime/python27\_lib/versions/1/google/appengine/api/files/file.py", line 388, in \_make\_rpc\_call\_with\_retry
\_make\_call(method, request, response)
File "/base/python27\_runtime/python27\_lib/versions/1/google/appengine/api/files/file.py", line 236, in \_make\_call
\_raise\_app\_error(e)
File "/base/python27\_runtime/python27\_lib/versions/1/google/appengine/api/files/file.py", line 179, in \_raise\_app\_error
raise FileNotOpenedError()
J'ai mené une enquête plus approfondie et, d'après un commentaire à l'adresse suivante Numéro 5371 de la GAE l'API Fichiers ferme le fichier toutes les 30 secondes. Je n'ai vu cela documenté nulle part ailleurs.
J'ai essayé de contourner le problème en fermant et en ouvrant le fichier à intervalles réguliers, mais j'obtiens maintenant une erreur de type WrongOpenModeError. J'ai ajouté une pause de 0,5 seconde entre la fermeture et l'ouverture du fichier. J'obtiens maintenant une erreur de type WrongOpenModeError.
Mon code (mis à jour) :
PATH = '/gs/backupbucket/'
for df in DocumentFile.all():
fn = df.blob.filename
br = blobstore.BlobReader(df.blob)
write_path = files.gs.create(self.PATH+fn.encode('utf-8'), mime_type='application/zip',acl='project-private')
fp = files.open(write_path, 'a')
c = 0
while True:
if (c == 5):
c = 0
fp.close()
files.finalize(write_path)
time.sleep(0.5)
fp = files.open(write_path, 'a')
c = c + 1
buf = br.read(100000)
if buf=="": break
fp.write(buf)
files.finalize(write_path)
Stacktrace :
Traceback (most recent call last):
File "/base/python27\_runtime/python27\_lib/versions/third\_party/webapp2-2.3/webapp2.py", line 1511, in \_\_call\_\_
rv = self.handle\_exception(request, response, e)
File "/base/python27\_runtime/python27\_lib/versions/third\_party/webapp2-2.3/webapp2.py", line 1505, in \_\_call\_\_
rv = self.router.dispatch(request, response)
File "/base/python27\_runtime/python27\_lib/versions/third\_party/webapp2-2.3/webapp2.py", line 1253, in default\_dispatcher
return route.handler\_adapter(request, response)
File "/base/python27\_runtime/python27\_lib/versions/third\_party/webapp2-2.3/webapp2.py", line 1077, in \_\_call\_\_
return handler.dispatch()
File "/base/python27\_runtime/python27\_lib/versions/third\_party/webapp2-2.3/webapp2.py", line 547, in dispatch
return self.handle\_exception(e, self.app.debug)
File "/base/python27\_runtime/python27\_lib/versions/third\_party/webapp2-2.3/webapp2.py", line 545, in dispatch
return method(\*args, \*\*kwargs)
File "/base/data/home/apps/s~simplerepository/1.354894420907462278/processFiles.py", line 267, in get
fp.write(buf)
File "/base/python27\_runtime/python27\_lib/versions/1/google/appengine/api/files/file.py", line 310, in write
self.\_make\_rpc\_call\_with\_retry('Append', request, response)
File "/base/python27\_runtime/python27\_lib/versions/1/google/appengine/api/files/file.py", line 388, in \_make\_rpc\_call\_with\_retry
\_make\_call(method, request, response)
File "/base/python27\_runtime/python27\_lib/versions/1/google/appengine/api/files/file.py", line 236, in \_make\_call
\_raise\_app\_error(e)
File "/base/python27\_runtime/python27\_lib/versions/1/google/appengine/api/files/file.py", line 188, in \_raise\_app\_error
raise WrongOpenModeError()
J'ai essayé de trouver des informations sur l'erreur WrongOpenModeError mais le seul endroit où elle est mentionnée est dans le fichier appengine.api.files.file.py lui-même.
Des suggestions sur la manière de contourner ce problème et de pouvoir enregistrer des fichiers volumineux sur le stockage Google Cloud seraient très appréciées. Merci de votre compréhension.