简体   繁体   中英

Python AsyncIO blocking

I have a basic script to import UK postcodes into a database with SQL Alchemy. To try to improve efficiency I am attempting to do this with AsyncIO following the docs and a number of "guide" blog posts.

The below is working (no exception thrown, imports into database correctly) however it is seemingly synchronous - both the file and respective rows are in order when I would expect all three files and rows as and whenever. I can't see why. How can it be fixed so that the import of each row in a given CSV does not block the import of the next?

import csv
import os
import asyncio
from db.db import Session, engine, Base
from Models.PostCode import PostCode
from sqlalchemy.exc import IntegrityError

Base.metadata.create_all(engine)

session = Session()
csv_path = os.path.dirname(os.path.realpath(__file__)) + '/postcode_lists/'

def runImport(fname):
    with open(csv_path + fname + '_postcodes.csv', newline='') as csvfile:
        reader = csv.DictReader(csvfile)

        tasks = [asyncio.ensure_future(saveRow(row)) for row in reader]

        loop = asyncio.get_event_loop()

        responses = loop.run_until_complete(asyncio.gather(*tasks, return_exceptions=True))
        loop.close()

        return responses


async def saveRow(row):
    if ('In Use?' not in row) or (row['In Use?']=='Yes'):
        await persist(row)

def persist(row):
    EXISTS = len(session.query(PostCode).filter(PostCode.postcode == row['Postcode']).all())
    if EXISTS == 0:
        pc = PostCode(
            row['Postcode'],
            )

        session.add(pc)
        session.commit()
        print(pc)
        return pc


datasets = ['CM', 'CO']
for d in datasets:
    runImport(d)

print(Done)

Output example

<PostCode(postcode='CA7 5HU')>
<PostCode(postcode='CA7 5HW')>
<PostCode(postcode='CA7 5HX')>
<PostCode(postcode='CA7 5HY')>
<PostCode(postcode='CA7 5HZ')>
<PostCode(postcode='CA7 5JB')>

I am expecting a somewhat jumbled output instead of alpha-ordered as per the CSV.

Bascially your problem is that there is no real async operation in your code.

Async is actually working as an event loop which is callback based. Your async operation will cause switching which means current task is hung up and the event loop will switch to another task.

But as all your tasks are totally blocking, so none of your task will cause hanging up and switching. Which means your code snippet is exactly the same as an ordered task queue.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM