Забегая вперед отмечу, что чистый файл зависимостей environment.yml создать пришлось. Но, во-первых, на старте его не было, а во-вторых, это гайд как создать с нуля. Поехали.
Простое решение: создать новое окружение на базе Anaconda Metapackage – готового набора популярных библиотек для Data Science, Data Analysis и Machine Learning с идеальной совместимостью версий.
# Anaconda Prompt: (base) C:\Users\YOUR_USERNAME>
# Создаем окружение с базовым набором Anaconda Metapackage
conda create --name ds-book anaconda
# Активируем его
conda activate ds-bookЭтот путь был выбран на старте, чтобы не заморачиваться потом с доустановкой необходимых пакетов и исправлением возможных конфликтов зависимостей.
Однако, оказавшись за стареньким дачным компом с нестабильным мобильным интернетом оказалось, что этот путь невозможен. Пришлось почерепить что действительно может понадобиться и разбил задачу на три этапа.
1.1. Создание изолированного окружения¶
# -- Этап 1 -- Anaconda Prompt: (base) C:\Users\YOUR_USERNAME>
# Создание conda-окружения и установка базовых пакетов
conda create --name ds-book -c conda-forge python=3.12 jupyterlab=4.4.7 ^
notebook=7.4.5 pandas numpy matplotlib seaborn scikit-learn ^
python-dotenv cryptography sqlalchemy -y
# Python -- 3.12 стабильный релиз из сбалансированного Anaconda Distribution
# Jupyter Lab -- 4.4.7 для совместимости с расширением `jupyterlab_myst`
# Jupyter Notebook -- 7.4.5 синхронизирован с базой JupyterLab 4.
conda activate ds-book| Пакет | Версия в проекте | Назначение |
|---|---|---|
python=3.12 | 3.12.13 | Ядро языка программирования |
jupyterlab=4.4.7 | 4.4.7 | Интерактивная среда разработки |
notebook=7.4.5 | 7.4.5 | Интерактивная среда разработки |
pandas | 3.0.5 | Классический анализ данных. Базовый инструмент обработки таблиц (DataFrames) |
numpy | 2.5.1 | Математические вычисления |
matplotlib | 3.11.1 | Базовые графики |
seaborn | 0.13.2 | Статистическая визуализация |
scikit-learn | 1.9.0 | Машинное обучение |
python-dotenv | 1.2.2 | Управление секретами. Безопасное хранение паролей БД и токенов в файлах .env |
cryptography | 50.0.0 | Шифрование данных. На случай продвинутой работы с секретами внутри Python |
sqlalchemy | 2.0.51 | Универсальный ORM-мост между Python и реляционными БД |
1.2. Установка инструментов верстки и коннекторов БД¶
# -- Этап 2 -- Anaconda Prompt: (ds-book) C:\Users\YOUR_USERNAME>
# Установка в conda инструментов верстки и коннекторов БД
conda install -c conda-forge jupyter-book mysql-connector-python ^
pymysql jupysql jupyterlab-myst| Пакет | Версия в проекте | Назначение |
|---|---|---|
| Jupyter Book | 2.1.6 | Для верстки сайта из файлов Markdown и блокнотов Jupyter |
| mysql | 9.7.0 | Драйвер базы данных MySQL для Python |
| pymysql | 1.2.0 | Драйвер-коннектор MySQL для SQLAlchemy |
| JupySQL | 0.11.1 | Расширение для работы с SQL в ячейках Jupyter c поддержкой подсветки синтаксиса |
| jupyterlab | 3.3.0 | Плагин для вывода времени исполнения запроса в строке статуса ячейки Jupyter Lab |
| jupyterlab_myst | 2.7.0 | Визуальный плагин разметки MyST для Lab. Рендерит внутри интерфейса во время работы |
Примечание по плагину jupyterlab_execute_time
jupyterlab_execute_timeДля автоматического вывода времени выполнения SQL-запросов в проекте используется интерфейсный плагин jupyterlab_execute_time. Из-за отставания версий в репозитории conda-forge плагин устанавливается через pip.
Подробный разбор причин такого решения, сравнение с магической командой %%time и особенности отображения таймингов в Jupyter Book вынес в отдельный раздел Бенчмаркинг SQL-запросов.
1.3. Установка Polars¶
Чтобы неожиданно не получить в Jupyter Lab Kernel Died (как произошло у меня на старом компе), хорошо бы знать какой на ПК процессор (CPU):
современный – с поддержкой AVX2;
или старый – без поддержки AVX2.
Установка Polars вынесена в отдельный раздел, чтобы разобрать грабли с архитектурой процессоров и показать, почему по умолчанию в environment.yml зафиксирован вариант через pip, но оставлена возможность переключиться на чистую conda для современного железа.
Из официальной документации установка производится через менеджер pip.
# Anaconda Prompt: (ds-book) C:\Users\YOUR_USERNAME>
# На современных CPU с поддержкой AVX2
pip install polars
# На старых CPU без поддержки AVX2
pip install polars[rtcompat]Обычный
pip install polarsставит одну версию, оптимизированную под современные CPU. Если запустить её на старом процессоре (без AVX2), она упадет с ошибкойIllegal instruction, что вызовет в Jupyter Lab падение ядраKernel Died.polars[rtcompat](runtime compatibility) – толстая установка. Она скачивает сразу несколько версий движка (скомпилированных под разные наборы инструкций) и во время импорта библиотеки выбирает нужный.
| Пакет | Версия в проекте | Назначение |
|---|---|---|
| Polars | 1.43.2 | Аналог Pandas. Мощный современный движок на Rust для щупанья альтернатив (на современных CPU) |
| polars[rtcompat] | 1.43.2 | На старых ПК: c автоматической поддержкой старых процессоров без AVX2 (через движок совместимости) |
Универсальность polars[rtcompat]
polars[rtcompat]На самом деле, пакет polars[rtcompat] – универсален. В него включены сразу несколько движков. При запуске на современном ПК он определит наличие AVX2 и активирует быстрый движок, а на старом процессоре переключится на режим совместимости.
Разница только в размере: polars[rtcompat] занимает больше места на диске (порядка 100 МБ) так как скачивает несколько версий библиотек.
Поскольку polars[rtcompat] оказался универсальным, то в environment.yml именно он зафиксирован для установки Polars по умолчанию.
Окружение проекта строим на Conda. Чтобы выяснить возможность установки пакетов через conda, проверим их доступность в репозиториях.
# Anaconda Prompt: (base) C:\Users\YOUR_USERNAME>
conda search -c conda-forge -c defaults polars
Loading channels: done
# Name Version Build Channel
... ... ... ...
polars 1.43.1 pyh8da0edf_0 conda-forge
polars 1.43.2 pyh8da0edf_0 conda-forge
polars 1.44.0 pyh8da0edf_0 conda-forge
polars 1.44.1 pyh8da0edf_0 conda-forge
polars 1.44.2 pyh3138b34_0 conda-forgeВидим, что на современном ПК установить polars через conda можем:
Префикс
pyh...в колонке Build обозначает пакет типаnoarch: python(метапакет-обертку), который не привязан к конкретной версии Python и одинаково успешно установится и на Python 3.10, и на наш 3.12.
А вот на старом ПК (без AVX2) устанавливать polars[rtcompat] придется через pip.
# Anaconda Prompt: (base) C:\Users\YOUR_USERNAME>
conda search -c conda-forge -c defaults polars-runtime-compat
Loading channels: done
# Name Version Build Channel
... ... ... ...
polars-runtime-compat 1.41.2 py310haa95532_0 pkgs/main
polars-runtime-compat 1.41.2 py311haa95532_0 pkgs/main
polars-runtime-compat 1.41.2 py312haa95532_0 pkgs/main # py312
polars-runtime-compat 1.41.2 py313haa95532_0 pkgs/main
polars-runtime-compat 1.41.2 py314haa95532_0 pkgs/main
... ... ... ...
polars-runtime-compat 1.44.1 py310h7f95213_0 conda-forge
polars-runtime-compat 1.44.1 py314h47234b9_0 conda-forge
polars-runtime-compat 1.44.2 py311hd8b5709_0 conda-forge
polars-runtime-compat 1.44.2 py314h47234b9_0 conda-forgeДля используемой в проекте версии Python 3.12:
Пакет совместимости (колонка Build версия
py312...) есть только в каналеpkgs/main(официальный репозиторий Anaconda: defaults). В каналеconda-forgeверсии для Python 3.12 на данный момент вообще нет. То есть если устанавливать черезconda, то необходимо добавить в установку основной канал-c defaults.Доступная версия в
pkgs/mainсильно устарела – 1.41.2 (тогда как в PyPI уже доступна 1.44.2). Между версиями Polars 1.41 и 1.44 разработчики могли исправить баги интеграции с SQLAlchemy или оптимизировать чтение из MySQL. Использовать старую версию пакета в проекте – это шаг назад (лишиться свежих исправлений и оптимизаций).В экосистеме
pip(на PyPI) такой проблемы нет – там всегда лежит актуальный универсальный wheel-пакет, который без проблем развернется в нашем окружении под Python 3.12.
Поскольку каналы Conda отстают от релизов и не имеют нужной сборки под Python 3.12, установку polars[rtcompat] фиксируем через pip.
Наличие точечно различающихся окружений в принципе нормальная практика в Data Science: на слабом железе используется совместимый рантайм polars[rtcompat], а на современном – максимально оптимизированный polars.
Поэтому при сборке окружения вручную, итоговый Этап 3 представляет два варианта на выбор:
# -- Этап 3 -- Установка Polars
# Anaconda Prompt: C:\Users\YOUR_USERNAME>
# Вариант 1: на любых CPU -- Универсальный установщик через `pip`
# (ds-book)
pip install polars[rtcompat]
# Вариант 2: только на современных CPU с AVX2 -- через `conda`
# (base)
conda install -n ds-book --override-channels -c conda-forge polarsДля установки в conda используем строгий и изолированный синтаксис:
conda используем строгий и изолированный синтаксис:-n ds-book– запускаем команду из (base), благодаря чему окружение (ds-book) остается холодным и Windows не блокирует его файлы.--override-channels– указываем Conda игнорировать глобальные настройки каналов в файле.condarc, чтобы исключить любые конфликты конфигураций.
Работая над проектом на двух разных машинах, я использую оба сценария:
на ПК с современным CPU работает чистый
polarsизconda;на старом ПК – универсальный
polars[rtcompat]изpip.
Чтобы убедиться, что ядро видит библиотеку и не падает:
# Проверить импорт внутри терминала Python
python
>>> import polars as pl
>>> print(pl.__version__)
1.43.2
>>> exit()# Проверить импорт в ячейке Jupyter Lab
import polars as pl
print(pl.__version__)
# 1.43.2Зачем понадобятся Pandas и Polars продемонстрировал в Главе 3.
1.4. Фиксация окружения¶
Окружение создано, все требуемые пакеты установлены – на этом можно было бы настройку рабочего пространства завершить.
Но это не наш метод. Потому что может сложиться ситуация, когда нам понадобится созданное окружение воссоздать. Поэтому потратим ещё какое-то количество времени и сохраним (зафиксируем) нашу работу в специальный файл зависимостей environment.yml.
С одной стороны, поскольку
condaсоздает окружения в своей системной папкеC:\Users\YOUR_USERNAME\anaconda3\envs, нам не обязательно сейчас находиться в корне проекта. То есть можем создать файл зависимостей в любом месте, а уже потом перенести в папку проекта.Однако по уму создавать
environment.ymlлучше все-таки сразу в корне проекта. Поэтому папку проекта создадим сразу.
Олдскульная привычка – отделять мух от котлет:
Системный диск
C:\– для программ;Для данных (проектов) – диск
D:\
Понятно, что второго диска может не быть: значит работаем с чем есть – меняем в гайде D:\ на C:\
Поскольку мы в Windows, папку проекта можем создать через штатный Проводник. Или продолжить в терминале:
# Anaconda Prompt: (ds-book) C:\Users\YOUR_USERNAME>
C:\Users\YOUR_USERNAME>D: # перейти на датадиск
D:\>cd GitHub\Books # перейти в родительскую папку проекта
# создать папку проекта и (&&) перейти в нее
mkdir Learning-SQL && cd Learning-SQLНаконец, готовы создать волшебный файл, в котором будут зафиксированы все зависимости созданного нами окружения. Создадим его, находясь в нашем окружении (об этом подсказывает в скобках имя окружения (ds-book) перед текстом командной строки):
# Anaconda Prompt: (ds-book) D:\GitHub\Books\Learning-SQL>
conda env export --no-builds > environment.ymlПосле создания открываем environment.yml (например, в VS Code) и ... вручную убираем лишнее, корректируем, добавляем комментарии, чтобы получить чистый понятный завершенный вариант, готовый к развертыванию на любом компе
name: ds-book
channels:
- conda-forge
- defaults
dependencies:
- python=3.12
- pip
# Среда разработки
- jupyterlab=4.4.7
- notebook=7.4.5
- jupyter-book=2.1.6
- jupyterlab-myst=2.7.0
# Анализ данных и визуализация
- pandas>=3.0.5
# - polars>=1.43.2 # на современных CPU с поддержкой AVX2
- numpy>=2.5.1
- matplotlib>=3.11.1
- seaborn>=0.13.2
- scikit-learn>=1.9.0
# Работа с БД
- sqlalchemy>=2.0.51
- mysql-connector-python>=9.7.0
- pymysql=1.2.0
- jupysql=0.11.1
# Утилиты
- python-dotenv
- cryptography
- pip:
- "polars[rtcompat]>=1.43.2" # и на старых и на современных CPU
- "jupyterlab_execute_time>=3.3.0"1.5. Воспроизведение окружения¶
При наличии файла environment.yml создание окружения на другом компе сводится к одной простой команде
# Находясь в корне планируемого проекта в базовом окружении
# Anaconda Prompt: (base) D:\GitHub\Books\Learning-SQL>
conda env create -f environment.yml1.6. Краткий чек-лист¶
# Этап 1: создание conda-окружения и установка базовых пакетов
conda create --name ds-book -c conda-forge python=3.12 jupyterlab=4.4.7 ^
notebook=7.4.5 pandas numpy matplotlib seaborn scikit-learn ^
python-dotenv cryptography sqlalchemy -y
# Активация окружения
conda activate ds-book
# Этап 2: установка в conda инструментов верстки и коннекторов БД
conda install -c conda-forge jupyter-book mysql-connector-python ^
pymysql jupysql jupyterlab-myst
# Этап 3: Установка Polars через менеджер `pip`
pip install polars[rtcompat]
# Фиксация окружения
conda env export --no-builds > environment.yml
# Воспроизведение окружения
conda env create -f environment.ymlСопутствующий СheatSheet
Команды которые пригодятся / могут пригодиться при настройке / тестировании окружения
# Практически НЕ используется:
# так как деактивация происходит при закрытии терминала
conda deactivate
# Полностью перезаписать `environment.yml`
conda env export --no-builds > environment.yml
# знак `>` полностью перезаписывает файл
# -- Обновить текущее окружение--
# (подтянуть до состояния актуального)
conda env update -f environment.yml --prune
# `update` – добавит недостающее
# `--prune` – удалит то, чего больше нет в файле
# -- Создать окружение с другим именем --
# отличным от указанного в environment.yml
conda env create -f environment.yml -n ds-test
# флаг `-n` перекрывает имя окружения, написанное внутри файла
# `ds-test` – задать имя тестируемого окружения
# -- Просмотреть состав текущего окружения --
conda list
# Eсли в `Channel` написано `pypi`: значит пакет установлен через `pip`
# Если пусто: пакет установлен менеджером Conda из основного канала `defaults`
# Если `conda-forge`: значит пакет взят из этого сообщества
# -- Посмотреть список всех окружений --
conda env list
# -- Удалить созданное окружение --
# находясь в базовом `(base)`
conda env remove -n ds-test
# флаг `-n` – это сокращение от слова `--name`
# -- Проверка наличия обновлений в `pip` --
# Нас интересует `Polars` – ищем его в списке
pip list --outdated
# Обновление `Polars`
pip install --upgrade polars[rtcompat]
# Проверить импорт внутри Python
python
>>> import polars as pl
>>> print(pl.__version__)
1.43.2
>>> exit()