Как выполнить асинхронную функцию в синхронной функции
Я создаю приложение и хочу, чтобы моя синхронная функция представления Django выполняла асинхронную функцию, которая сохраняет большое количество элементов базы данных. Я делаю это, потому что хочу, чтобы мое представление Django быстро выполняло процесс, пока некоторые сложные вещи происходят в фоновом режиме, не позволяя пользователю увидеть экран загрузки. Однако это работает не так, как я предполагал.
Вот мой код
Views.py
from django.shortcuts import render
import pandas as pd
from .models import Visit
from .task import saving_csv_in_database
from .form import *
import asyncio
def upload_files(request):
form = UploadFileForm(request.POST or None, request.FILES or None)
if form.is_valid():
csvfile = request.FILES['file_name']
try:
data = pd.read_csv(csvfile)
except FileNotFoundError:
return render(request, 'error.html')
arr = data.to_dict('records')
context = {'d': arr}
asyncio.run(saving_csv_in_database(arr))
return render(request, 'upload.html', context)
return render(request, 'record.html', {'form': form})
task.py
from .models import *
async def saving_csv_in_database(arr):
patient_instances = []
for record in arr:
patient_instance = Visit(
patient=Patients.objects.create(
medical_record=record['mr_number'],
first_name=record['first_name'],
last_name=record['last_name'],
date_of_birth=record['dob']
),
date=record['date'],
reason=record['reason']
)
patient_instances.append(patient_instance)
Visit.objects.bulk_create(patient_instances)
y= print("Hi I have entered the entries in database")
return y
Я также использовал сельдерей вот мой код
вот мой views.py
def upload_files(request):
form = UploadFileForm(request.POST or None, request.FILES or None)
if form.is_valid():
csvfile = request.FILES['file_name']
try:
data = pd.read_csv(csvfile)
except FileNotFoundError:
return render(request, 'error.html')
arr = data.to_dict('records')
context = {'d': arr}
saving_csv_in_database.delay(arr)
return render(request, 'upload.html', context)
return render(request, 'record.html', {'form': form})
вот мой task.py
from .models import *
from celery import shared_task
@shared_task(bind=True)
def saving_csv_in_database(arr):
patient_instances = []
for record in arr:
patient_instance = Visit(
patient=Patients.objects.create(
medical_record=record['mr_number'],
first_name=record['first_name'],
last_name=record['last_name'],
date_of_birth=record['dob']
),
date=record['date'],
reason=record['reason']
)
patient_instances.append(patient_instance)
Visit.objects.bulk_create(patient_instances)
y= print("Hi I have entered the entries in database")
return y
и я получаю эту ошибку
TypeError: saving_csv_in_database() takes 1 positional argument but 2 were given
Я не понимаю эту ошибку
Пожалуйста, дайте мне знать, что не так, и как я могу это сделать. Я просто хочу, чтобы мое сохранение в базе данных выполнялось отдельно в потоке
Первый путь
def upload_files(request):
....
loop = asyncio.new_event_loop()
loop.run_until_complete(saving_csv_in_database(arr))
....
Второй способ
from asgiref.sync import async_to_sync
def upload_files(request):
....
async_to_sync(saving_csv_in_database)(arr)
....