使用 uv 构建隔离的数据管道环境:Data Engineering Zoomcamp 虚拟环境实战

使用 uv 构建隔离的数据管道环境:Data Engineering Zoomcamp 虚拟环境实战 使用 uv 构建隔离的数据管道环境Data Engineering Zoomcamp 虚拟环境实战【免费下载链接】data-engineering-zoomcampData Engineering Zoomcamp is a free 9-week course on building production-ready data pipelines. Join the course here 项目地址: https://gitcode.com/GitHub_Trending/da/data-engineering-zoomcamp在数据工程实践中一个典型的数据管道data pipeline会经历读取数据 → 转换处理 → 落地存储的完整生命周期。本篇指南以 Data Engineering Zoomcamp 的cohorts/2027/01-docker-terraform模块为背景讲解如何使用uv这一现代化 Python 包管理器创建隔离的虚拟环境、管理依赖并运行数据管道脚本。学完本篇你将掌握虚拟环境的原理与必要性、uv的核心命令工作流以及如何将本地环境无缝迁移到 Docker 容器中的完整路径。数据管道接收数据、输出数据的服务数据管道是一种以数据为输入、以数据为输出的服务。以最简单的形式为例读取一个 CSV 文件对数据进行某种转换然后将其存储为 PostgreSQL 数据库中的一张表。在本模块的 workshop 中我们将构建具备以下能力的管道从网络下载 CSV 数据使用 pandas 转换和清洗数据将数据加载到 PostgreSQL 中以供查询分块chunk处理数据以应对大文件仓库中完整的落地实现位于 pipeline 目录包含摄取脚本、Dockerfile、docker-compose 配置与辅助脚本后续章节会逐步对照说明。创建第一个简单管道首先创建一个pipeline目录并在其中创建文件pipeline.pyimport sys print(arguments, sys.argv) day int(sys.argv[1]) print(fRunning pipeline for day {day})这个脚本演示了管道最基础的形态通过命令行参数接收输入某一天的编号打印出运行信息。接下来引入 pandas让管道具备真正的数据处理能力import pandas as pd df pd.DataFrame({A: [1, 2], B: [3, 4]}) print(df.head()) df.to_parquet(foutput_day_{sys.argv[1]}.parquet)此时管道会构造一个 DataFrame、打印其内容并把结果输出为按日期命名的 Parquet 文件——这就是数据输入 → 转换 → 输出的雏形。为什么需要虚拟环境现在管道依赖 pandas但系统中并没有安装它。在正式进入容器container之前我们希望先在本地测试脚本。最直接的方式是用pip安装pip install pandas pyarrow但这样做会把包全局安装到系统 Python 中。如果不同项目需要同一个包的不同版本全局安装就会引发版本冲突。例如项目 A 需要pandas 1.x而项目 B 需要pandas 2.x全局共存几乎不可能。解决方案是使用虚拟环境virtual environment一个相互隔离的 Python 环境将当前项目的依赖与其他项目、以及系统 Python 彻底分隔开。虚拟环境保证依赖隔离每个项目拥有独立的包集合与版本环境可复现配合锁文件可以精确重建相同的运行环境系统安全不会污染系统级 Python也不会被系统升级破坏。uv更现代的 Python 包管理器本模块采用uv——一个用 Rust 编写的高性能 Python 包与项目管理器。它比pip快得多并且自动管理虚拟环境省去了手动创建与激活环境的繁琐步骤。安装 uvpip install uv然后初始化一个 Python 项目uv init --python3.13该命令会生成两个关键文件pyproject.toml项目的依赖声明文件项目元数据 依赖列表.python-version锁定项目使用的 Python 版本。同时 uv 会自动创建虚拟环境.venv目录。仓库中真实的 pyproject.toml 展示了项目化后的完整形态[project] name pipeline version 0.1.0 description Add your description here readme README.md requires-python 3.13 dependencies [ click8.3.1, pandas2.3.3, psycopg2-binary2.9.11, pyarrow22.0.0, sqlalchemy2.0.44, tqdm4.67.1, ] [dependency-groups] dev [ jupyter1.1.1, pgcli4.3.0, ]可以看到requires-python 3.13与uv init --python3.13一一对应而dev依赖组则专门放 Jupyter、pgcli 这类仅用于开发调试的工具。对比虚拟环境与系统 Python执行下面的命令可以直观看到两种 Python 的差异uv run which python # Python in the virtual environment uv run python -V which python # System Python python -Vuv run会优先使用虚拟环境中的解释器因此两条命令输出的路径与版本号通常不同——这正是环境隔离的直观证明uv run运行在独立环境中不依赖也不影响系统 Python。添加依赖并运行管道向项目添加 pandas 与 pyarrowuv add pandas pyarrow该命令会把依赖写入pyproject.toml并同步安装到虚拟环境中。随后即可运行管道uv run python pipeline.py 10预期的输出为[pipeline.py, 10]job finished successfully for day 10sys.argv列表中的两个元素分别对应脚本名和传入的参数10说明管道已正确接收并处理了命令行输入。从示例到真实工程仓库中的完整摄取管道示例管道演示了概念而仓库 pipeline/ingest_data.py 给出了生产级的完整实现——将 NY 出租车数据摄取到 PostgreSQL 的脚本。它与示例管道一脉相承但补充了大量工程细节命令行参数解析使用click声明式定义参数核心参数包括--pg-user、--pg-pass、--pg-host、--pg-port默认 5432、--pg-db默认ny_taxi、--year、--month、--target-table与--chunksize默认 100000显式数据类型通过dtype字典为 16 个字段指定类型如VendorID用Int64、金额字段用float64、store_and_fwd_flag用string避免 pandas 在读取大文件时因列类型混合产生DtypeWarning日期解析通过parse_dates列表将tpep_pickup_datetime与tpep_dropoff_datetime解析为时间戳分块摄取pd.read_csv(..., iteratorTrue, chunksize100000)按 10 万行一批读取数据配合tqdm进度条逐块写入 PostgreSQL——这正是原文档强调的处理大文件能力的工程化体现。分块写入的完整循环逻辑如下与 05-data-ingestion.md 中的 Jupyter 版本一致第一块数据用df_chunk.head(0).to_sql(..., if_existsreplace)仅创建表结构后续每块数据用if_existsappend追加写入。执行摄取脚本的命令为uv run python ingest_data.py \ --pg-userroot \ --pg-passroot \ --pg-hostlocalhost \ --pg-port5432 \ --pg-dbny_taxi \ --target-tableyellow_taxi_trips从虚拟环境到容器uv 保证环境一致性虚拟环境解决的是本地开发的一致性而生产运行还需要容器。uv 的优势在于同一套依赖声明pyproject.tomluv.lock既可以驱动本地虚拟环境也可以驱动 Docker 镜像构建实现本地与容器完全一致。仓库 pipeline/Dockerfile 展示了这一实践FROM python:3.13.11-slim COPY --fromghcr.io/astral-sh/uv:latest /uv /bin/ WORKDIR /code ENV PATH/code/.venv/bin:$PATH COPY pyproject.toml .python-version uv.lock ./ RUN uv sync --locked COPY ingest_data.py . ENTRYPOINT [python, ingest_data.py]逐行解读FROM python:3.13.11-slim使用精简版 Python 3.13 镜像缩小镜像体积COPY --fromghcr.io/astral-sh/uv:latest /uv /bin/从官方 uv 镜像复制 uv 二进制多阶段构建模式WORKDIR /code设置容器内工作目录ENV PATH/code/.venv/bin:$PATH把虚拟环境加入 PATH使容器内可直接使用已安装的包COPY pyproject.toml .python-version uv.lock ./先复制依赖清单文件充分利用 Docker 层缓存RUN uv sync --locked基于锁文件安装依赖--locked确保安装版本与锁定版本完全一致构建可复现COPY ingest_data.py .复制应用代码ENTRYPOINT [python, ingest_data.py]容器启动时执行摄取脚本。值得一提的是uv init时生成的uv.lock锁文件是环境可复现的关键它精确记录了每个依赖及其传递依赖的版本哈希无论本地还是容器uv sync --locked都会还原出完全相同的依赖树。在 03-dockerizing-pipeline.md 中还给出了两种 Dockerfile 写法pip install版与 uv 版的对比uv 版在构建速度与可复现性上更优。Git 配置防止提交生成文件管道运行后会产生 Parquet 等二进制产物这些文件不应进入版本控制。在.gitignore中添加*.parquet这样 git 会忽略所有 Parquet 文件避免把大型二进制文件误提交到仓库中。同理虚拟环境目录.venv/也应纳入忽略列表因为它是可随时重建的本地产物。小结通过本篇实战你完成了从零构建数据管道的完整链路理解数据管道输入 → 转换 → 输出的基本形态理解虚拟环境解决全局依赖冲突的核心价值掌握uv的完整工作流uv init→uv add→uv run通过which python对比验证环境隔离效果对照 pipeline 目录了解生产级摄取脚本的分块处理与参数化设计理解 uv 锁文件如何让 Docker 镜像与本地环境保持一致通过.gitignore管理生成文件。这套虚拟环境 uv 锁文件 Dockerfile的组合正是后续模块中所有数据管道项目标准化环境管理的基石。接下来可以继续阅读 Dockerizing the Pipeline 与 Running PostgreSQL with Docker将管道真正容器化并连接数据库。【免费下载链接】data-engineering-zoomcampData Engineering Zoomcamp is a free 9-week course on building production-ready data pipelines. Join the course here 项目地址: https://gitcode.com/GitHub_Trending/da/data-engineering-zoomcamp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考