Я работаю над проектом Django (Django 1.10, Python 3.4.3), где я пытаюсь загрузить файл в подпроцессе python. Мне нужно загрузить файл и рассчитать некоторые суммы на нем, когда я его загружу, и мы хотим, чтобы система по-прежнему использовалась, когда она это делает, поэтому мы думали, что эти задачи будут выполняться в подпроцессе.Загрузить файл в подпроцессе python
Сейчас я работаю над загрузкой файла.
ПЕРВАЯ ПОПЫТКА:
приложения/просмотры/UploadView.py
class NewUploadView(TemplateView):
template_name = "../templates/simulation/upload.html"
@transaction.atomic
def post(self, request):
if request.method == 'POST':
if not request.FILES['input_file']:
return HttpResponseBadRequest("No 'input_file' is provided")
else:
sim_name = self.request.POST.get(u"name", None)
p = Popen(["/.virtualenvs/env/bin/python3.4", "manage.py",
"load_simulation", str(request.FILES['input_file'],
str(sim_name)])
p.communicate()
# Redirect to appropriate page
HttpResponseRedirect(reverse('home.display_simulations'))`
приложения/Управление/Команды/load_simulation.py
import csv
import os
from django.conf import settings
from django.core.management.base import BaseCommand
from website.apps.home.models import Simulation, Location, Data, SimulationModel
class Command(BaseCommand):
help = 'Upload csv data file and save objects in database'
def add_arguments(self, parser):
parser.add_argument("my_file", type=str)
parser.add_argument("simulation_name", type=str)
def handle(self, *args, **options):
"""
Upload data file
:param args:
:param options:
:return:
"""
my_file = options["my_file"]
simulation_name = options["simulation_name"]
# Save the simulation object, with the data_file
simulation = Simulation.objects.create(name=simulation_name, data_file=my_file)
simulation.save()
filename = os.path.join(settings.MEDIA_ROOT, "simulation_files", simulation.getfilename())
file_obj = open(filename, 'r')
dictreader = csv.DictReader(file_obj)
line = None
for line in dictreader:
location = Location.objects.filter(
department_code=line['department_code'],
municipality_code=line['municipality_code'],
).first()
if not location:
location = Location.objects.create(
department=line['department'],
department_code=line['department_code'],
municipality=line['municipality'],
municipality_code=line['municipality_code'],
)
Data.objects.create(
location=location,
date=line['date'].split(" ")[0], # Assuming date is in "YYYY-MM-DD HH:MM:SS" format
simulation=simulation,
value_low=line['value_low'],
value_mid=line['value_mid'],
value_high=line['value_high'],
)
simulation.is_uploaded = True
simulation.save()
print("DONE WITH LOAD SIMULATION!")
Я его настройте так, чтобы файл был сохранен в /media/simulation_files
Справочник. Но файл не будет сохранен на сервере, а это значит, что он сбой в файле load_simulation.py
в строке, где он пытается открыть файл, так как файл не находится в этом месте.
Тогда я понял, что я проходил в TemporaryFile как строку, так что, возможно, это часть проблемы.
ВТОРАЯ ПОПЫТКА
Я изменил часть UploadView.py взять в файл как стандартный ввод.
p = Popen(["/.virtualenvs/env/bin/python3.4", "manage.py",
"load_simulation", str(sim_name), is_historical],
stdin=PIPE)
p.communicate(input=request.FILES['output_file'])
и модифицированный load_simulation.py начать следующим образом:
class Command(BaseCommand):
help = 'Upload csv data file and save objects in database'
def add_arguments(self, parser):
parser.add_argument("my_file", type=str)
parser.add_argument("simulation_name", type=str)
def handle(self, *args, **options):
"""
Upload data file
:param args:
:param options:
:return:
"""
simulation_name = options["simulation_name"]
my_file = input()
# Save the simulation object, with the data_file
simulation = Simulation.objects.create(name=simulation_name, data_file=my_file.name)
simulation.save()
filename = os.path.join(settings.MEDIA_ROOT, "simulation_files", simulation.getfilename())
file_obj = open(filename, 'r')
dictreader = csv.DictReader(file_obj)
... same as before ...
, который я получил от следующего вопроса/ответа: Python3 subprocess communicate example
Это дает мне ошибку
TypeError: 'InMemoryUploadedFile' does not support the buffer interface
Я новичок в работе с подпроцессами и не понимаю, что попробовать дальше. Я действительно понимаю, что p.communicate()
может быть не лучшим выбором здесь, но я надеюсь, что это сработает, чтобы получить базовую функциональность, а затем я могу ее улучшить. Предложения и советы наиболее ценятся!