Блокировка Python AsyncIO - PullRequest
       26

Блокировка Python AsyncIO

0 голосов
/ 06 октября 2018

У меня есть базовый скрипт для импорта почтовых индексов Великобритании в базу данных с помощью SQL Alchemy.Чтобы попытаться повысить эффективность, я пытаюсь сделать это с помощью AsyncIO, следуя документам и ряду «руководящих» постов в блоге.

Ниже работает (без исключений, импортируется в базу данных правильно), однако, на первый взглядсинхронный - и файл, и соответствующие строки расположены по порядку, когда я ожидаю все три файла и строки, как и когда-либо.Я не понимаю почему.Как это можно исправить, чтобы импорт каждой строки в данном CSV не блокировал импорт следующей?

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)

Пример вывода

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

Я ожидаю несколько беспорядочного вывода вместо альфа-упорядоченного согласно CSV.

1 Ответ

0 голосов
/ 06 октября 2018

По сути, ваша проблема в том, что в вашем коде нет реальной асинхронной операции.

Асинхронная работа фактически работает как цикл обработки событий, основанный на обратном вызове.Ваша асинхронная операция вызовет переключение, что означает, что текущая задача зависла, и цикл обработки событий переключится на другую задачу.

Но так как все ваши задачи полностью блокируются, то ни одна из ваших задач не вызовет зависания и переключения.Это означает, что ваш фрагмент кода точно такой же, как и упорядоченная очередь задач.

...