LINUX.ORG.RU

aiomysql: выдает ошибку при попытке импорта

 , , ,


0

1

Друзья, простите заранее за нубский вопрос, совсем еще новичок в Python. Пытаюсь написать фреймворк с использованием aiohttp и в качестве библиотеки для асинхронной работы с БД пытаюсь использовать aiomysql. aiomysql установил, но при попытке импорта библиотеки, вылезает вот такая ошибка (pymysql тоже установлено):

Traceback (most recent call last): File «<stdin>», line 1, in <module> File «C:\Users\AAA\AppData\Local\Programs\Python\Python36-32\lib\site-packages\aiomysql\__init__.py», line 32, in <module> from .connection import Connection, connect File «C:\Users\AAA\AppData\Local\Programs\Python\Python36-32\lib\site-packages\aiomysql\connection.py», line 30, in <module> from pymysql.connections import _scramble ImportError: cannot import name '_scramble'

Помогите плиз разобраться с чем связана эта ошибка и как исправить?

И второй вопрос - правильно ли я делаю, что использую aiomysql или есть другие библиотеки для асинхронной работы с Mysql?

Заранее огромное спасибо!

C:\Users\AAA\AppData\Local\Programs\

вот с этим ты явно не туда забрёл...

И второй вопрос - правильно ли я делаю, что использую aiomysql

Для домашних поделок, да, вполне. Если будет что-то чуть более-менее нагруженное и нужна ассинхронность, то mysqlclient (остальные врапперы в разы тормознее) + ThreadPoolExecutor(ProcessPoolExecutor).

А так, я бы наверное посоветовал aiopg + postgre.

vvn_black ★★★★ ()
Ответ на: комментарий от vvn_black

Спасибо за совет! Правильно ли я понял, что блокирующие операции с mysqlclient оборачивать в ThreadPoolExecutor и запускать в отдельном потоке? И это все будет работать с асинхронным aiohttp?

Luhashan ()
Ответ на: комментарий от Luhashan

И еще вопрос про aioodbc. Вот пример из документации, однако мне как новичку совершенно не понятно, как именно заполнять dsn. Например какой драйвер указывать и откуда его вообще брать?

import asyncio import aioodbc

loop = asyncio.get_event_loop()

async def test_example(): dsn = 'Driver=SQLite;Database=sqlite.db' conn = await aioodbc.connect(dsn=dsn, loop=loop)

cur = await conn.cursor() await cur.execute(«SELECT 42;») r = await cur.fetchall() print(r) await cur.close() await conn.close()

loop.run_until_complete(test_example())

Luhashan ()
Ответ на: комментарий от vvn_black

Спасибо, буду гуглить и изучать! Если не сложно, может есть под рукой ссылка на понимание того, что такое ODBC-сервер для новичка, если на английском, то даже лучше?

Luhashan ()
Ответ на: комментарий от vvn_black

Оо хренасе ты ему посоветовал..
потоки сами по себе дорогое удовольствие (именно для асинхронности) дак еще и под виндой. если нужна асинхронность и производительность - то только гринлеты, желательно под libuv. если просто асинхронность - то aio, собственно что он и взял.
да и самый быстрый коннектор вроде как ultramysql, ничего быстрее пока не встречал. для третьего есть форк

genryRar ★★ ()
Ответ на: комментарий от genryRar

ultramysql

Я как-то мимо него прошёл, даже не слышал.

Оо хренасе ты ему посоветовал..

Ну а что... aiomysql - это PyMySQL, у меня на одном запросе разница с mysqlclient была в 10 раз.

aioodbc - штука может и выглядит привлекательно, но я в своё время наелся глюков с оракловским mysql odbc коннектором. А их саппорт... Я так и не смог пройти первую линию.

только гринлеты

Всё может быть. Только в тренде async/await.

дак еще и под виндой

ССЗБ. Я кстати даже не принимал это во внимание )

P.S. А ещё я посоветовал aiopg )

vvn_black ★★★★ ()
Последнее исправление: vvn_black (всего исправлений: 2)
Ответ на: комментарий от vvn_black

Я как-то мимо него прошёл, даже не слышал.

если актуально будет - советую заценить. вдогонку еще ultrajson от тогоже автора

Всё может быть. Только в тренде async/await.

мыж вроде про производительность :) какая разница что там в тренде. но даже если так, async-await это всеголишь сахар для техже коротин. меняем дефолтный луп на uvloop и вот тебе теже гринлеты. вариант с gevent+libuv мне нравится больше но обьективно разница невелика.

Ну а что... aiomysql - это PyMySQL, у меня на одном запросе разница с mysqlclient была в 10 раз.

вполне логично, pymysql это pure-py изначально делавшийся для pypy, где от него и есть профит. само собой он ощутимо медленнее mysqldb (форком которого является mysqlclient). но поскольку mysqldb несовместима ни с aio ни с gevent, то с ней приходится юзать потоки. и вот тут уже все совсем неочевидно - при высокой нагрузке медленный pymysql но с гринлетами ощутимо её обгоняет по скорости, дак еще и памяти жрет в несколько раз меньше (правда это именно для высокой нагрузки справедливо, если у тебя всего десяток одновременных запросов то mysqldb будет быстрее). а если вместо pymysql взять ultra версию - ну сам понимаешь

genryRar ★★ ()
Ответ на: комментарий от genryRar

Посоветуйте тогда новичку стек технологий для асинхронного сервера на Питоне. Сейчас я себе так мыслю: aiohttp redis для хранения сессий и прочей служебной информации mysqlclient с потоками для хранения более тяжелого контента jinja2 шаблонизатор страниц хранилище сессий и авторизацию планирую написать самостоятельно. Что скажите?

Luhashan ()
Ответ на: комментарий от Luhashan

Посоветуйте тогда новичку стек технологий для асинхронного сервера на Питоне.

С этого и надо было начинать, всё придумано до нас https://demos.aiohttp.org/en/latest/

ну вот только авторизацию, действительно, придётся делать самому.

vvn_black ★★★★ ()
Последнее исправление: vvn_black (всего исправлений: 2)
Ответ на: комментарий от Luhashan

насколько я понимаю речь про хоумпейдж\непродакшен? тогда:

aiohttp

если на 3 питоне, то однозначно

redis для хранения сессий и прочей служебной информации

в данном случае звено немного лишнее, но почему бы и нет - полезный опыт

mysqlclient с потоками для хранения более тяжелого контента

абсолютно бессмысленно в данном случае. я не про mysql в общем, это дело вкуса. я про сишный коннектор, несовместимый с асинхронностью. он нужен для весьма специфичных кейсов - в обычном случае используй aio-совместимую реализацию. да, @vvn_black прав и питоновская реализация коннектора работает медленнее сишной «в лоб». но вопервых производительность это не то, что тебе сейчас нужно (а когда будет нужно - решать это нужно иными способами). а во вторых смешивание коротин (aio*) и нативных потоков это всегда лишний геморрой и имеет смысл только если ты понимаешь, зачем тебе это.

jinja2 шаблонизатор страниц

опять таки дело вкуса, плюс он популярный - значит опять полезный опыт

хранилище сессий и авторизацию планирую написать самостоятельно

на этапе обучения - почему бы и нет, и этот опыт пригодится - хотябы для общего понимания как оно внутри может быть устроено.
просто помни, что за исключением специфичных кейсов (обучение в них попадает) писать свой велосипед смысла нет и лучше взять готовый стек. темболее когда речь о всем что связано с безопасностью или продакшен-риди
p.s.
@vvn_black дал неплохую ссылку, как минимум стоит ознакомиться. ряд решений там спорный, но всеже

genryRar ★★ ()
Последнее исправление: genryRar (всего исправлений: 2)
Ответ на: комментарий от genryRar

Ой, большое вам спасибо за рекомендации! Есть пара вопросов: 1. А если речь идет о продакшен, что из этого стека вы не рекомендовали бы использовать и что на что заменить? 2. «в обычном случае используй aio-совместимую реализацию. да, @vvn_black прав и питоновская реализация коннектора работает медленнее сишной «в лоб». но вопервых производительность это не то, что тебе сейчас нужно (а когда будет нужно - решать это нужно иными способами). а во вторых смешивание коротин (aio*) и нативных потоков это всегда лишний геморрой и имеет смысл только если ты понимаешь, зачем тебе это» Тут сразу два вопроса: я разумеется попробую для начала aio-совместимую реализацию, но хотелось бы просто на будущее уточнить про «иные способы» повышения производительности - чтобы было что почитать в свободное время. И второй — ведь asyncio сама предлагает смешивать де-факто однопотоковые корутины и нативные потоки - в библиотеке есть функция run_in_executor, которая возвращает корутину. «Зачем это»? — ну вот например, грузит клиент на сервер файл, его нужно принять и как то сохранить. Операция блокирующая, у меня ничего в голову не приходит, как завернуть ее в executor и выполнить в отдельном потоке, чтобы работа сервера в момент записи не блокировалась. Или я ошибаюсь и есть иные способы? Еще раз огромное спасибо за разъяснения.

Luhashan ()
Ответ на: комментарий от Luhashan

А если речь идет о продакшен, что из этого стека вы не рекомендовали бы использовать и что на что заменить?

а если речь о продакшене - то зависит от конкретного проекта, предполагаемой нагрузки и вариантов масштабирования.
универсального совета тут нет, в качестве общих рекомендаций - не писать свой велосипед для того, что касается безопасности (сессии и авторизация) и по возможности брать готовый популярный стек - типа какойнибуть джанги, ну или фласка -если хочется чуть меньше абстракций. соответственно все типовые задачи решать компонентами для этого стека. да даже тотже aio* можно взять в качестве фреймворка - у них есть репозиторий с кучей готовых компонентов, в том числе https://github.com/aio-libs/aiohttp-session и https://github.com/aio-libs/aiohttp-security. правда такой сценарий всеже менее популярен, чем фласк и джанга - соответственно в случае граблей меньше доступной информации. собственно этим продакшен и отличается принципиально - нужно брать популярные инструменты.

хотелось бы просто на будущее уточнить про «иные способы» повышения производительности

правильный путь повышения производительности:
1. aio или аналогичные коротины (например gevent)
2. libuv, например через uvloop или напрямую
3. pypy либо замена библиотек на сишные, но совместимые с коротинами
4. переписывание критичных частей на Си
соответственно с ростом нагрузки ты идеш по этим шагам последовательно. при правильной архитектуре и разумно выбранных библиотеках первые три шага проходятся без скольконибуть существенных изменений в коде.

ведь asyncio сама предлагает смешивать де-факто однопотоковые корутины и нативные потоки

не предлагает, а позволяет. на то он и питон «гибкий, аж из рук выскальзывает». да, есть ситуации, в которых смешивание коротин и потоков может дать ощутимый профит - например в случае асинхронного сервера приблизившегося к нагрузке 900+ новых соединений в секунду, если обрабатываемые запросы не успевают отрабатываться за 1ms (блокирующий код при обработке выполняется дольше), использование дополнительного потока для вызова обработчиков порежет скорость НО увеличит отзывчивость сервера и позволит обработать еще больше соединений - естественно при этом увеличится задержка на получение результата. но такой подход требует четкого понимания, как все это работает, ПОЧЕМУ это работает и как при этом не отстрелить себе обе ноги. также как отключение сборщика мусора - это может дать неслабый бурст при длительной высокой нагрузке, но нужно понимать как при этом не замусорить память.

поэтому без острой необходимости в продакшене (да и не в продакшене) не стоит так делать.

например, грузит клиент на сервер файл, его нужно принять и как то сохранить. Операция блокирующая, у меня ничего в голову не приходит, как завернуть ее в executor и выполнить в отдельном потоке, чтобы работа сервера в момент записи не блокировалась. Или я ошибаюсь и есть иные способы?

само собой есть другие способы. любая операция ввода-вывода может быть асинхронной, работа с файлами ничем не примечательна. например можно так https://github.com/mosquito/aiofile

но даже если бы операция была понастоящему блокирующей - надежнее создать дочерний процесс, который бы занимался обработкой именно таких операций и отправлять ему «задание» из основного процесса. а результата ждать асинхронно, само собой.

повторюсь - смешивание коротин и нативных потоков, это очень скользкий путь. и нужно четкое понимание зачем это делается и как в таком случае ведет себя интерпритатор. и если необходимость в этом возникла (понастоящему возникла, а не из разряда «мне лень искать как сделать работу с файлами асинхронно» или «мне лень делать ручное переключение контекста по таймауту в моем блокирующем коде») то это тревожный звоночек - похоже в твоей архитектуре чтото нетак.

genryRar ★★ ()