BorisovAI
Все публикации
Новая функцияtrend-analisisClaude Code

Как миграция БД свалилась в production и чему я научился

Как миграция БД свалилась в production и чему я научился

Работаю я над Trend Analysis — системой анализа тенденций в Python. Недавно понадобилось добавить новую колонку max_web_citations в таблицу объектов. Звучит просто, но история развивалась неожиданно.

Сначала я добавил миграцию в _classify_via_objects() — выполнил ALTER TABLE, проверил локально, отправил в production. Казалось, всё работает. Но через несколько часов упало: “no such column: o.max_web_citations”.

Оказалось, что я обновил таблицу в одном месте, но забыл про get_trend_classes() — функцию, которая читает эту же таблицу. Она вызывалась до первого classify, и SELECT падал на несуществующей колонке.

Вроде глупая ошибка, но она раскрыла важный паттерн: когда добавляешь колонку — это не локальный fixes, нужно grep’ить все SELECT-запросы к этой таблице и убедиться, что миграция прокатывается ДО первого чтения.

Исправил обе функции, перезапустил — помогло. Потом ещё два часа лепил lint-fixes. В итоге из простого изменения получилось три этапа отладки.

Пока копался в коде, наткнулся на другой паттерн в документации — про асинхронные операции. Там советуют использовать asyncio.wait(FIRST_COMPLETED) вместо gather(), когда частичные отказы приемлемы. Микросервисы часто дёргают 3–5 нисходящих API одновременно, и обычно нужен первый результат, а не все. asyncio.wait позволяет перехватить первый отказ быстро, применить circuit breaker и вернуть частичный результат. Это снижает каскадные отказы и задержки.

IoT-компании, оказывается, падают именно из-за задержек обработки событий. Они смотрят на p99 latency и крутят ручку asyncio-оптимизации. Компании с низкой задержкой и хорошей асинхронной архитектурой лучше совпадают спрос с предложением.

Мне показалось, что в нашей системе сам я использую gather() в старом коде, где можно было бы asyncio.wait со слабой связанностью. Не критично, но это напомнило — техдолг растёт незаметно, когда не смотришь на архитектуру в целом.

Итог: добавляй колонки честно — ищи все места, где они используются. И асинхронный код проектируй с запасом на сбои, не на идеальный сценарий. А если Python работает — и вправду не трогай. Если не работает — тоже иногда лучше оставить как есть. 😄

Метаданные

Session ID:
grouped_trend-analisis_20260225_1119
Branch:
main
Dev Joke
Если React работает — не трогай. Если не работает — тоже не трогай, станет хуже.

Оцените материал

0/1000