👨💻** Как выгрузить большой объём данных (SQL, API и т.п.) по частям в Python с помощью батчинга:**
Когда данных слишком много — например, тысячи ID для выгрузки из базы или API — обрабатывать всё сразу рискованно: можно словить таймаут, ошибку или просто “зависание”. Здесь на помощь приходит батчинг — разбиение на маленькие порции.
1️⃣ Представим, что у нас крупный сервис по доставке еды и нас попросили посмотреть по определенным пользователям их количество покупок за август. Нам предоставили список в виде excel файла c user_id (там список порядка 300 тыс.пользователей), по которым нужно собрать статистику. Отлично, давайте писать код:
import pandas as pd
from utils import sql_query #Представим, что это функция, которая берет на вход sql запрос и возвращает результат в Pandas DataFrame
user_id_df = pd.read_excel('user_id.xlsx') #Загружаем файл с user_id в Pandas DataFrame
user_id_tuple = tuple(user_id_df['user_id']) #Преобразуем в формат кортежа, чтобы можно было подставить удобно в sql запрос через f строку Python
sql_query("""select
user_id,
count(*)
from events
where
user_id in {user_id_tuple} #подставляем через f строку наши user_id
and event_date between '2025-08-01' and '2025-08-31' #рассматриваем август
and event_name = 'purchase' #смотрим события покупки
group by
1
""")
Все отлично, но такой запрос, скорее всего, упадет с ошибкой, так как список с user_id нам дали большой и событий соответственно тоже много и СУБД выдаст ошибку, чтобы защититься от “падения”. Что делать в таком случае? Ответ - а давайте ограничим выборку, а как мы ее можем ограничить? Давайте будем смотреть не сразу всех user_id из списка, а по частям.
2️⃣ Функция для разбиения списка на n равных частей:
def split_into_n_parts(lst, n=10):
k = len(lst) // n #Целочисленное деление (Например, 23//10 = 2)
m = len(lst) % n #Остаток от деления (Например, 23//10 = 3)
parts = [] #Результат
start = 0
for i in range(n):
size = k + (1 if i < m else 0)
end = start + size
parts.append(lst[start:end])
start = end
return parts
Вот наша функция: она берёт список lst и делит его на ровно n частей (по умолчанию 10). Остаток распределяется по первым частям для равномерности.
3️⃣ Применим функцию и выполним итоговый запрос по частям и объединим все в один DataFrame:
user_id_list = list(user_id_df['user_id']) #Преобразуем в формат списка, чтобы можно было подставить в нашу функцию для батчинга
iters = split_into_n_parts(user_id_list, 10) #Получили список у которого в качестве элементов другие списки, например [[1,2,3] , [4,5,6]] и т.д.
df_list = [] #Сюда будем запихивать промежуточные результаты, чтобы в конце их объединить
for batch_user_id_list in iters:
df_add = sql_query("""select
user_id,
count(*)
from events
where
user_id in {tuple(batch_user_id_list)} #подставляем через f строку наши user_id
and event_date between '2025-08-01' and '2025-08-31' #рассматриваем август
and event_name = 'purchase' #смотрим события покупки
group by
1)
df_list.append(df_add)
# Объединяем все DataFrame в один
df_buy = pd.concat(df_list, ignore_index=True)
Вуаля, мы смогли выгрузить все нужные нам данные.
Итог:
• Батчинг — супер-инструмент для работы с большими данными в Python. С этой функцией и циклом вы легко обработаете любые объёмы без сбоев!
• Вопрос, который может возникнуть — а что если нужно по всем user_id информацию выгрузить за тот же август, то уже не выйдет так сделать ? Ответ — выйдет, но для этого, как правило используют хэш функцию (Об этом в одном из следующих постов).
🍸 Если вы нашли пост для себя полезным, то накидывайте реакций, чтобы я понимал, что вам эта тема интересна!
❤️Поддержать канал бустами, чтобы у автора появился дополнительный функционал можно - здесь (это бесплатно и доступно с подпиской telegram premium)
❓ Как вам объяснение? Пробовали подобное для выгрузки данных? Делитесь в комментариях!