Ошибка tmpfile с django-import-export на Heroku

Я использую django-import-export для обработки файлов CSV, загруженных на мой админ-сайт Django.

Когда я запускаю Django на моей локальной машине, все работает нормально.

При развертывании приложения в Heroku появляются ошибки, связанные с доступом к tmpfile:

Feb 24 14:35:12 test-staging app/web.3:  ERROR 2017-02-24 22:35:12,143 base 14 139687073408832 Internal Server Error: 
....
Feb 24 14:35:12 test-staging app/web.3:    File "/app/.heroku/python/lib/python2.7/site-packages/import_export/admin.py", line 163, in process_import 
Feb 24 14:35:12 test-staging app/web.3:      data = tmp_storage.read(input_format.get_read_mode()) 
Feb 24 14:35:12 test-staging app/web.3:    File "/app/.heroku/python/lib/python2.7/site-packages/import_export/tmp_storages.py", line 42, in read 
Feb 24 14:35:12 test-staging app/web.3:      with self.open(mode=mode) as file: 
Feb 24 14:35:12 test-staging app/web.3:    File "/app/.heroku/python/lib/python2.7/site-packages/import_export/tmp_storages.py", line 31, in open 
Feb 24 14:35:12 test-staging app/web.3:      return open(self.get_full_path(), mode) 
Feb 24 14:35:12 test-staging app/web.3:  IOError: [Errno 2] No such file or directory: u'/tmp/tmpvCUtrP' 

Я прочитал о том, что я могу об эфемерном хранилище Heroku, похоже, это должно сработать. Я подтвердил, что могу создавать, просматривать и изменять файлы в / tmp на сервере Heroku Dyno с помощью своего кода с помощью команды heroku.

В django-import-export есть модуль, который позволяет вам перегрузить механизм создания временного файла, но я даже не уверен, что здесь не так (или, скорее, почему /tmp/tmpvCUtrP не создается или не отображается).

2 ответа

Решение

django-import-export разделяет процесс импорта на несколько запросов к серверу.

Heroku может использовать несколько dyno, которые не разделяют общую файловую систему в /tmp.

Случайно начальный запрос может сделать dyno A и создать tmpfile в /tmp/tmpfilename, а затем более поздний запрос может перейти к dyno B, а для django-import-export требуется /tmp/tmpfilename, но это не так.,

Чтобы обойти это, я переключился на метод временного хранения CacheStorage django-import-export:

from import_export.tmp_storages import CacheStorage

class CustomAdminForm(ImportExportModelAdmin):
    tmp_storage_class = CacheStorage

Анализ первопричины в ответе мертвым кодом верен. В средах, где кэш настроен неправильно, ноdefault_storage(например, для S3), вы также можете использовать следующее:

      from import_export.tmp_storages import MediaStorage

@admin.register(MyModel)
class MyModelAdmin(ImportExportMixin, admin.ModelAdmin):
    tmp_storage_class = MediaStorage

Другие вопросы по тегам