👨‍💻** Как выгрузить большой объём данных (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)

❓ Как вам объяснение? Пробовали подобное для выгрузки данных? Делитесь в комментариях!

@@dima_sqlit


Ссылки