Noor ul ain Ibrahim
Noor ul ain Ibrahim

Reputation: 107

How to execute an Asynchronus function in synchrounous function

I'm creating an app, and I want my synchronous Django view function to execute an asynchronous function that saves a large number of database items. I'm doing that because I want my Django view to quickly carry out the process while some complicated things are going in the background, preventing the user from seeing the loading screen. However, it is not operating as I had anticipated.

Here is my code

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

I have also used celery here is my code

here is my 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})

here is my 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

and I am getting this error

TypeError: saving_csv_in_database() takes 1 positional argument but 2 were given

I don't understand this error

Please let me know what's wrong, and how I can do it. I just want my saving thing on database to run separately in a thread

Upvotes: 2

Views: 116

Answers (1)

Rasim Mammadov
Rasim Mammadov

Reputation: 171

First way

def upload_files(request):
    ....
    loop = asyncio.new_event_loop()
    loop.run_until_complete(saving_csv_in_database(arr))
    ....

Second way

from asgiref.sync import async_to_sync

def upload_files(request):
    ....
    async_to_sync(saving_csv_in_database)(arr)
    ....

Upvotes: 1

Related Questions