Ich arbeite an einem Django-Projekt (Django 1.10, Python 3.4.3), wo ich versuche, eine Datei in einen Python-Subprozess hochzuladen. Ich muss die Datei hochladen und einige Summen berechnen, während ich sie hochlade, und wir möchten, dass das System währenddessen noch verwendbar ist. Daher dachten wir, diese Aufgaben in einen Subprozess zu stellen.Hochladen einer Datei in einen Python-Subprozess
Momentan arbeite ich gerade daran, die Datei hochzuladen.
Erster Versuch:
app/views/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'))`
app/Management/Befehle/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!")
ich es habe eingerichtet, so dass die Datei ingespeichert wirdVerzeichnis. Die Datei wird jedoch nicht auf dem Server gespeichert, was bedeutet, dass sie in der Datei load_simulation.py
an der Zeile fehlschlägt, in der sie versucht, die Datei zu öffnen, da sich die Datei nicht an diesem Speicherort befindet.
Dann erkannte ich, dass ich eine temporäre Datei als Zeichenfolge übergeben, also ist das vielleicht ein Teil des Problems.
zweiter Versuch
Ich änderte Teil UploadView.py in der Datei als stdin zu nehmen.
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'])
und modifizierte load_simulation.py beginnen wie folgt:
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 ...
, die ich aus der folgenden Frage/Antwort bekam: Python3 subprocess communicate example
Das gibt mir einen Fehler
TypeError: 'InMemoryUploadedFile' does not support the buffer interface
Ich bin neu mit Subprozessen zu arbeiten und bin ratlos, was ich als nächstes versuchen soll. Ich bin mir bewusst, dass p.communicate()
hier vielleicht nicht die beste Wahl ist, aber ich hoffe, dass es funktionieren wird, um die grundlegende Funktionalität herunter zu bekommen und dann kann ich sie verbessern. Vorschläge und Ratschläge werden sehr geschätzt!