Мы всё про тот же самый пример, в котором вы утверждаете что что среди айдишников может быть DROP DATABASE?
Нет, я бегло проверил другие примеры и нашёл подходящий. Я о том и говорю, что многие люди не понимают языка человеческого. Поэтому начнём с дропнутой БД, а потом плавно перейдём к работе над ошибками
Джунам раз за разом объясняют -- конкатенация и форматирование SQL зло, И раз за разом одни и те же SQL инъекции. В одном из примеров инъекцию вы точно прошляпили. Поэтому и спрашиваю про прод -- человеческий язык не все понимают. То ли дело язык упавшего прода
Да, а фласк позволяет запускать event loop в каждой вьюхе. Значит ли это, что во фласке "не все там" плохо с асинхронностью? Да кому она нужна в таком виде?
Celery всегда был синхронным и всегда в воркере выполнялась ровно одна таска (если без eventlet/greenlet).
У вас чёрный пояс по взаимоисключающим параграфам. Оруэлл одобряет. Помимо перечисленных вами, селери поддерживает другие пулы, и кроме перечисленных я знаю ещё про threadpool-executor.
Я даже не знаю, как так можно в одном предложении опровергнуть себя же?
взять все CPU-bound таски
Отсебятина.
Asyncio совсем не поможет если вы запускаете обсчет матрицы или какую-нибудь ML-задачу
Ещё один интересный парадокс. Когда в собственном проде мы качаем/клеим файлы (IO), отправляем почту и вебхуки (IO) или процессим транзакции (IO), вы аппелируете к CPU-bound задаче. То есть как бы и да -- asyncio на CPU-bound бесполезен. Но и как бы и нет -- большинство задач IO-bound, включая ваш собственный пример
И вообще, почему Вы отметаете вариант, что в подобных случаях наиболее эффективный способ выполнения поставленной задачи (план) просто тупо совпадает с текстом задания (запрос)?
Именно. Сложный запрос можно составить десятками разных способов, из которых два-три могут конкурировать по производительности, а все остальные являются или саботажем, или бездарностью. В своё время я насмотрелся на бездарность
Не аксиома. Запрос с подзапросом запросто может быть развёрнут анализатором
Редко, но оптимизаторы меня действительно удивляют. Иногда приятно, чаще нет. Как по мне, чем предсказуемее оптимизатор, тем ниже вероятность сюрприза на проде. Одно приятное удивление было в примере бездарного кода:
WHERE TRUNC(event_log.event_time, "YYYY.MM") = :event_day
Так вот, вместо честного TABLE FULL ACCESS оптимизатор смог использовать INDEX RANGE SCAN, разве что выгреб годовой интервал вместо суток
Но.. В celery и так всегда одна таска на воркер! :)
Аргументация в стиле:
-- Но позвольте, вы творите технический абсурд
-- Все так делают :)
У меня довольно крупные таски - например, скачать 50 гигабайтных файлов и объединить в один - прекрасно качаются все параллельно.
Идея разделения на таски в том, что в случае ошибки мы всегда можем восстановить прогресс с минимальными потерями. Ваш подход предполагает написание своего менеджера загрузок
Кстати об оптимизаторе запросов. Воображение рисует, каким будет реально работающий оптимизатор запросов. Это должен быть робот, который находит программистов, пишущих плохой код, и нещадно их 3.1415926
Даже замена всех SQL запросов захардкоженными параметрами на параметризуемые даёт крайне низкий профит по производительности (другое дело, что эта срань отравляет кэш запросов, но о нём далее)
Наконец, БД кэширует как разобранные запросы, так и позволяет работать с prepared statements -- теми самыми скомпилированными запросами
Что реально даёт профит:
Внимательный разбор плана каждого мало-мальски сложного запроса
В случае ORM внимательный анализ запросов, которые она генерит
Наконец, ORM не позволяет забить на изучение SQL и RDBMs
А ещё декларативность SQL -- миф. В случае подзапросов БД выполнит их императивно -- начиная с самого глубоко вложенного и наверх
Прикол в том, что __slots__ становятся очень интересны при их использовании не по назначению. Мне особенно доставляет их использование в DTO -- это позволяет компактнее сериализировать объекты (см. msgpack)
Эти советы надо знать, я согласен. Но они порой очень детски наивные. На то он и совет, чтобы в общем прислушиваться, а в исключительных случаях игнорировать (вовсе не потому, что так захотелось -- на то должны быть веские основания)
Важно не забывать, что в разных языках разная специфика. Питонячий префикс "_" -- это только верхушка айсберга. В том же JS есть свои приколы, которые заставляют решать задачу сильно иначе
На старте он поистине прекрасен. Проблемы начинаются, когда ООП заменяется компонентно-ориентированноым программированием и когда формочки залетают на сервер. Насмотрелся в своё время
Нет, я бегло проверил другие примеры и нашёл подходящий. Я о том и говорю, что многие люди не понимают языка человеческого. Поэтому начнём с дропнутой БД, а потом плавно перейдём к работе над ошибками
Джунам раз за разом объясняют -- конкатенация и форматирование SQL зло, И раз за разом одни и те же SQL инъекции. В одном из примеров инъекцию вы точно прошляпили. Поэтому и спрашиваю про прод -- человеческий язык не все понимают. То ли дело язык упавшего прода
String sql = String.format("DELETE FROM %s WHERE gid IN (%s)", layerName, StringUtils.join(deletesIds, ','));
Ням-ням. В одном из айдишников может быть значение:
И начнётся развлекательная программа. Где ваш продакшн?
Да, а фласк позволяет запускать event loop в каждой вьюхе. Значит ли это, что во фласке "не все там" плохо с асинхронностью? Да кому она нужна в таком виде?
У вас чёрный пояс по взаимоисключающим параграфам. Оруэлл одобряет. Помимо перечисленных вами, селери поддерживает другие пулы, и кроме перечисленных я знаю ещё про threadpool-executor.
Я даже не знаю, как так можно в одном предложении опровергнуть себя же?
Отсебятина.
Ещё один интересный парадокс. Когда в собственном проде мы качаем/клеим файлы (IO), отправляем почту и вебхуки (IO) или процессим транзакции (IO), вы аппелируете к CPU-bound задаче. То есть как бы и да -- asyncio на CPU-bound бесполезен. Но и как бы и нет -- большинство задач IO-bound, включая ваш собственный пример
Я не вижу задачу невыполнимой ни в каком виде
Именно. Сложный запрос можно составить десятками разных способов, из которых два-три могут конкурировать по производительности, а все остальные являются или саботажем, или бездарностью. В своё время я насмотрелся на бездарность
Редко, но оптимизаторы меня действительно удивляют. Иногда приятно, чаще нет. Как по мне, чем предсказуемее оптимизатор, тем ниже вероятность сюрприза на проде. Одно приятное удивление было в примере бездарного кода:
Так вот, вместо честного
TABLE FULL ACCESS
оптимизатор смог использоватьINDEX RANGE SCAN
, разве что выгреб годовой интервал вместо сутокАргументация в стиле:
-- Но позвольте, вы творите технический абсурд
-- Все так делают :)
Идея разделения на таски в том, что в случае ошибки мы всегда можем восстановить прогресс с минимальными потерями. Ваш подход предполагает написание своего менеджера загрузок
То есть одна таска селери на воркер. Эффективность. Вы перечёркиваете все преимущества
asyncio
Именно. Все преимущества
asyncio
перечёркнутыЕсть обходной путь -- celery-pool-asyncio. Но это дикий костыль
Предлагаете дублировать код?
одну. асинхронную. таску. Э -- эффективность
В Celery всё очень плохо с asyncio
Почему статья в хабе Django?
Кстати об оптимизаторе запросов. Воображение рисует, каким будет реально работающий оптимизатор запросов. Это должен быть робот, который находит программистов, пишущих плохой код, и нещадно их
3.1415926
Выигрыш будет сильно меньше, чем хотелось бы:
Основное время БД находится в ожидании IO
Даже замена всех SQL запросов захардкоженными параметрами на параметризуемые даёт крайне низкий профит по производительности (другое дело, что эта срань отравляет кэш запросов, но о нём далее)
Наконец, БД кэширует как разобранные запросы, так и позволяет работать с prepared statements -- теми самыми скомпилированными запросами
Что реально даёт профит:
Внимательный разбор плана каждого мало-мальски сложного запроса
В случае ORM внимательный анализ запросов, которые она генерит
Наконец, ORM не позволяет забить на изучение SQL и RDBMs
А ещё декларативность SQL -- миф. В случае подзапросов БД выполнит их императивно -- начиная с самого глубоко вложенного и наверх
Пересекаются. Плохо только, что до этого сразу не додумались, а только в 3.10 -- ИМХО очевиднейшая вещь
Прикол в том, что
__slots__
становятся очень интересны при их использовании не по назначению. Мне особенно доставляет их использование в DTO -- это позволяет компактнее сериализировать объекты (см. msgpack)Эти советы надо знать, я согласен. Но они порой очень детски наивные. На то он и совет, чтобы в общем прислушиваться, а в исключительных случаях игнорировать (вовсе не потому, что так захотелось -- на то должны быть веские основания)
Важно не забывать, что в разных языках разная специфика. Питонячий префикс "_" -- это только верхушка айсберга. В том же JS есть свои приколы, которые заставляют решать задачу сильно иначе
Вывод: думать надо своей головой
На старте он поистине прекрасен. Проблемы начинаются, когда ООП заменяется компонентно-ориентированноым программированием и когда формочки залетают на сервер. Насмотрелся в своё время
Не могу вспомнить, когда я его себе ставил, но он у меня есть. Возможно, он в зависимостях
python3-all
-- а я не склонен искать себе лишний геморройUPD: хм, действительно, у меня установлен отдельный пакет
python3-tk
И даже что-то похожее есть: https://pypi.org/project/pyreact2/
Но там всё равно о генерации HTML и конкатенации строк
Delphi -- это такой же мем, как и Гуф
У tkinter есть одно важное преимущество -- он точно есть везде, где есть python.
Но убожество мегагалактическое в текущем виде, это да. И проблема не в том, что оно плохо работает, а в том, что production код писать на нём сложно