У меня есть функция, которая обрабатывает zip-файл csvs в моем приложении Django. Я вызываю функцию после нажатия кнопки при рендеринге представления путем создания нового потока и отправки функции в качестве метода run. Вот функция, которую я хочу вызвать:
update_db.py
def upload_files(csv_files):
conn = sqlite3.connect('/path/to/db.db')
c = conn.cursor()
for csv_filename in csv_files.namelist():
if csv_filename.endswith('.csv'):
csv_file = csv_files.open(csv_filename)
# extract team name from csv_file string, remove whitespace
table_name = csv_filename.rsplit('/',2)[1]
table_name = re.sub('[^\w+]', '', table_name)
try:
df = pandas.read_csv(csv_file, error_bad_lines=False)
df.to_sql(table_name, conn, if_exists='append', index=False)
##do some stuff
except pandas.errors.EmptyDataError as ex:
print(str(csv_file) + ' was empty; continuing...')
continue;
conn.commit()
conn.close()
Проблема в том, что функция прекрасно работает, если я вызываю ее в представлениях, но если я пытаюсь передать ее в поток, она не работает. Вот что я имею в среде вызова:
def upload(request):
if request.method == 'POST' and request.FILES['myfile']:
myfile = request.FILES['myfile']
if str(myfile.name).endswith('.zip'):
unzipped = zipfile.ZipFile(myfile)
# If I uncomment this line, it doesn't throw an error
#upload_files(unzipped)
# When these lines execute, I get an error
t = threading.Thread(target = upload_files, args = (unzipped, ))
t.daemon = True
t.start()
return render(request, 'webapp/upload.html', {
'success': True
})
return render(request, 'webapp/upload.html', {
'success': False
})
Вот трассировка стека:
Exception in thread Thread-7:
Traceback (most recent call last):
File "/usr/lib64/python3.6/threading.py", line 916, in _bootstrap_inner
self.run()
File "/usr/lib64/python3.6/threading.py", line 864, in run
self._target(*self._args, **self._kwargs)
File "/home/ec2-user/environment/0xDEADBEEF_Football/football/webapp/scripts/update_db.py", line 19, in upload_files
csv_file = csv_files.open(csv_filename)
File "/usr/lib64/python3.6/zipfile.py", line 1368, in open
fheader = zef_file.read(sizeFileHeader)
File "/usr/lib64/python3.6/zipfile.py", line 705, in read
self._file.seek(self._pos)
File "/usr/lib64/python3.6/tempfile.py", line 483, in func_wrapper
return func(*args, **kwargs)
ValueError: seek of closed file
Почему запуск функции в отдельном потоке вызывает ошибку, и как лучше всего решить проблему?