Сильнее вместе: Python, датафреймы и SQL
Много лет, работая в области данных и аналитической инженерии, я ценил ежедневное общение в небольшом офисе с талантливыми людьми, использующими различные инструменты — от аналитиков, работающих с SQL и Excel, до дата-сайентистов, работающих с Python. Я всегда чувствовал, что у нас есть много возможностей для совместной работы, но изолированные данные и инструменты делали это гораздо сложнее. Разнообразие наших инструментов и языков делало потенциал для сотрудничества еще более интересным, поскольку у нас могли быть люди с разными областями экспертизы, каждый из которых вносил бы свой уникальный вклад в проект. Но с логистической точки зрения это просто не могло быть реализовано в масштабируемом виде.
Поэтому я не могу быть более взволнован возможностями полиглотности dbt, которые появились в dbt Core 1.3. Этот релиз приносит библиотеки датафреймов Python, которые важны для дата-сайентистов, и позволяет использовать Python общего назначения, но при этом использует общую базу данных для чтения и записи наборов данных. Аналитические инженеры и дата-сайентисты сильнее вместе, и я не могу дождаться, чтобы работать бок о бок в одном репозитории со всеми моими друзьями-дата-сайентистами.
Переход на полиглотность — это важный следующий шаг в развитии dbt Core. Хотя это расширяет возможности, мы также признаем потенциал для путаницы. Когда они объединены намеренно, SQL, датафреймы и Python также сильнее вместе. Полиглотный dbt позволяет информированным практикам выбирать язык, который лучше всего подходит для вашего случая использования.
В этом посте мы дадим вам практический опыт и вдохновим ваше воображение потенциальными приложениями. Мы проведем вас через демонстрацию, которая демонстрирует разбор строк — один из простых способов, как Python может быть инте грирован в проект dbt.
Мы также предоставим вам интеллектуальные ресурсы для сравнения:
- различных реализаций датафреймов в разных платформах данных
- датафреймы против SQL
Наконец, мы поделимся "подводными камнями" и лучшими практиками, которые мы узнали до сих пор, и пригласим вас участвовать в поиске ответов на нерешенные вопросы, которые нас самих все еще интересуют.
На основе нашего раннего опыта, мы рекомендуем вам:
✅ Делайте: Используйте Python, когда он лучше подходит для задачи — обучение моделей, использование предсказательных моделей, матричные операции, исследовательский анализ данных (EDA), пакеты Python, которые могут помочь с комплексными трансформациями, и другие случаи, когда Python является более естественным решением для проблемы, которую вы пытаетесь решить.
❌ Не делайте: Используйте Python там, где решение на SQL столь же прямолинейно. Хотя чисто Python проект dbt возможен, мы ожидаем, что наиболее значимые проекты будут смесью SQL и Python.
Полиглотный dbt: Сплав Python, датафреймов и SQL
dbt Core 1.3 дает вам возможность использовать модели Python для материализации датафреймов как таблиц в вашем dbt DAG. В комбинации, модели Python и SQL формируют сплав в проекте dbt, создавая новые свойства, которых нет в изоляции.
Это одновременное двухчастное разблокирование. Во-первых, мы получаем язык программирования общего назначения в Python. Во-вторых, мы получаем доступ к специализированным библиотекам датафреймов для чтения из/записи в базу данных.
Некоторые довольно крутые функции следуют:
- Обширная экосистема пакетов Python: Богатая экосистема пакетов Python является сердцем различных случаев использования, таких как машинное обучение, исследовательский анализ данных (EDA), генерация наборов данных и многие, многие другие.
- Синтаксис датафреймов для манипуляции наборами данных: Существует активное сообщество разработчиков, ориентированных на Python, которые могут легче вносить вклад в проекты dbt, когда они могут использовать синтаксис датафреймов. Это особенно полезно в сочетании с случаями использования в области науки о данных.
- Рабочие процессы Python там, где находятся ваши данные: Большая часть работы с Python сегодня выполняется вне платформы данных, которая хранит исходные данные, что означает, что разработчикам сначала нужно перенести данные в среду Python, что добавляет значительное трение в рабочий процесс разработки. В случае Snowpark DataFrames перемещение данных сокращается за счет переноса вычислений на платформу данных.
Компромиссы между SQL и синтаксисом датафреймов
Как только вы настроитесь, следующий вопрос: для чего следует использовать Python? Как следует думать о компромиссах между SQL и датафреймами? Я лично не задумывался об этом глубоко... но ребята из Ponder задумывались 😉 Они опубликовали серию постов, сравнивающих их с точки зрения:
- удобства - датафреймы хорошо сочетаются с библиотеками науки о данных, такими как Scikit-learn
- краткости - датафреймы имеют краткий синтаксис для нормализации, one-hot кодирования, скользящих средних и других применений
- гибкости - строки и столбцы в датафреймах могут быть транспонированы, и функции могут быть применены вдоль столбцов или строк
Получение вашего собственного понимания этих различий позволит вам создать свой собственный сплав полиглотных моделей dbt.
Сравнение библиотек датафреймов
Прежде чем мы перейдем к нашему практическому примеру, давайте взглянем на детали настройки вашего проекта с различными типами датафреймов. Несколько платформ данных и библиотек датафреймов поддерживаются в dbt Core начиная с версии 1.3, но не равномерно (см. таблицу совместимости ниже). См. здесь для инструкций по настройке для конкретной платформы.
Тип датафрейма | Snowflake | Databricks | BigQuery |
---|---|---|---|
Snowpark DataFrames | ✅ | ❌ | ❌ |
pandas DataFrames | ✅ | ✅ | ✅ |
Spark DataFrames | ❌ | ✅ | ✅ |
pandas-on-Spark DataFrames | ❌ | ✅ | ✅ |
Koalas DataFrames | ❌ | ✅ | ✅ |
Более детальные сравнения и компромиссы
Snowpark DataFrames поддерживаются только в Snowflake, в то время как Spark DataFrames доступны только на Databricks и BigQuery. Также стоит помнить, что разные типы датафреймов используют разный синтаксис.
Мы намеренно не включили Jinja в модели Python: основное использование Jinja заключается в управлении потоком и доступе к динамическим переменным, что можно сделать в Python! Другое основное использование Jinja в dbt — создание абстракций для различных синтаксисов баз данных. На данный момент нет единой абстракции синтаксиса для различных типов датафреймов. (Но кто-то, вероятно, создаст одну!)
Хотя pandas DataFrames могут показаться идеальным решением из-за их поддержки на различных платформах данных, они имеют свои собственные компромиссы. Например, они не могут воспользоваться эффективностью нативных типов, таких как Spark и Snowpark DataFrames. Они также ограничены памятью — большие наборы данных быстро исчерпают доступную память. В дополнение к этому, они ограничены однопоточностью, поэтому не могут использовать несколько ядер. Хотя pandas можно параллелизовать с помощью решений, таких как Dask, Modin и т.д., как Snowpark, так и Spark DataFrames будут обрабатывать эти проблемы масштабирования нативно. Поэтому используйте Snowpark, pandas-on-Spark DataFrames и Spark DataFrames, когда это возможно! (Примечание: pandas-on-Spark DataFrames ранее были известны как Koalas DataFrames и теперь обычно называются pandas API DataFrames.)
В Snowflake любые трансформации Snowpark DataFrame, указанные в Python, фактически компилируются в SQL перед выполнением.
Первый практический опыт использования пакета Python
Теперь, когда у нас есть достаточный фон, давайте погрузимся в реальный случай использования.
Полный исходный код для этой демонстрации доступен по адресу:
Этот пример использует DuckDB в качестве базы данных. Вы можете использовать этот же код, скопировав его в свой проект, который использует ваш адаптер базы данных.
Наш пример даст вам практический опыт с тремя вещами:
- чтение данных из таблицы в датафрейм
- разбор унифицированных дат и времени из различн ых строковых форматов с использованием библиотеки
dateutil
- запись результата обратно в таблицу
Разбор дат/времени — это распространенный случай использования, потому что даты и время повсеместны в транзакционных исходных данных. Часто исходный формат неизвестен, и он может даже быть смесью нескольких форматов. Пакет dateutil
имеет метод, который будет делать попытку разбора строки в объект даты и времени Python, и он вызовет исключение, когда не сможет разобрать ввод. (Пользователи pandas могут уже быть знакомы с методом pandas.to_datetime
, который использует dateutil
). Следующая демонстрация использует dateutil
для разбора исходных данных с неизвестными форматами даты/времени.
В этом примере мы:
- Установим требования в виртуальной среде
- Построим проект dbt
- Проверим вывод
Компоненты проекта dbt
Этот проект dbt имеет только две основные части (помимо наш их исходных данных для имитации исходных данных):
- Логика трансформации в модели dbt Python
- Конфигурация тестирования данных для обеспечения качества
Модель dbt на Python
import dateutil
def try_dateutil_parse(x):
try:
return dateutil.parser.parse(x)
except:
return
def model(dbt, session):
df = dbt.ref("source_data")
df['parsed_transaction_time'] = df['transaction_time'].apply(try_dateutil_parse)
return df
Эта модель пытается разобрать необработанное строковое значение в объект даты и времени Python. Когда это не удается, она возвращает значение None
, а не вызывает ошибку. dateutil
может обрабатывать более широкий диапазон форматов, чем большинство нативных функций платформ данных.
Тестирование результата
Во время процесса сборки dbt проверит, есть ли какие-либо значен ия null. Это использует встроенный тест not_null
, который будет генерировать и выполнять SQL на платформе данных.
Наше первоначальное предложение для тестирования моделей Python — использовать общие и единичные тесты.
version: 2
models:
- name: transactions
columns:
- name: parsed_transaction_time
tests:
- not_null
Загрузка репозитория и установка требований
Полный исходный код для этой демонстрации доступен по адресу:
Единственные предварительные условия для этой демонстрации — это python3
и git
. Вы можете убедиться, что оба установлены и вы используете правильную версию, с помощью этих команд в вашем терминале:
python3 --version
git --version
Предполагая, что оба доступны в вашей системе, вы можете клонировать пример репозитория, используя ваш предпочтительный метод:
HTTPS
git clone https://github.com/dbt-labs/demo-python-blog.git
cd demo-python-blog