PAYATHON 2026

AWS MWAA 如何通过 S3 requirements.txt 自动更新 Python 包?

数据小许

结论

仅上传一次不带版本号的 requirements.txt,MWAA 不会持续自动追踪 PyPI 的最新发布。要实现无人值守更新,需要通过自动化流程定期触发依赖解析和 MWAA 环境更新。

还需要分别确认 MWAA 是否执行了依赖安装,以及 pip 在这次安装中是否需要升级已有包。不写版本号只影响版本要求,不会自动创建更新任务。

S3 文件更新是否会自动触发安装?

仅覆盖 S3 中的 requirements.txt,并不意味着 MWAA 已采用该文件的新版本。

MWAA 使用指定的 S3 对象版本。AWS 文档要求上传文件后,在环境配置中选择对应版本;也可以调用 UpdateEnvironment,设置 RequirementsS3ObjectVersion。MWAA 的依赖安装命令为 pip3 install -r requirements.txt。AWS 依赖安装说明、UpdateEnvironment API

如果上传后确实会自动更新环境,应检查是否已经配置了 CI/CD、Lambda 或其他自动化触发器。

不指定版本,为什么仍可能没有升级?

原问题中的文件是:

requests
pandas

这两行没有限制包的版本。实际结果还取决于已安装的软件包、constraints、Python 版本和包之间的依赖关系。

  • 如果需要安装某个包,pip 通常会选择满足全部约束的最新可用稳定版本。
  • 如果已有版本满足要求,普通的 pip install -r requirements.txt 可以保留该版本。
  • 添加 --upgrade 后,pip 才会主动尝试升级直接指定的包;间接依赖默认按 only-if-needed 策略处理。

重新执行安装,并不代表所有包都会升级到 PyPI 最新版本。pip install 文档

constraints 可能限制可安装版本

即使 requirements.txt 只写包名,Airflow constraints 仍可能固定这些包的版本。AWS 文档说明,从 Apache Airflow v2.7.2 开始,如果未提供 --constraint,MWAA 会补充相应约束。

合理的目标是安装当前 MWAA、Airflow 和 Python 环境下满足约束的版本。如果 PyPI 最新版与约束冲突,升级选项也不能绕过这种冲突。AWS constraints 说明

缓存不等于保留已安装版本

pip 的 HTTP 和 wheel 缓存主要用于减少重复下载与构建。发现版本没变时,应先检查是否触发了环境更新、是否启用了升级,以及 constraints 是否限制了版本。

--no-cache-dir 不会开启自动升级;--force-reinstall 表示重新安装,也不代表必须选择更新版本。pip 缓存说明、pip 安装选项说明

POC:保留包名清单,自动触发升级

如果希望保留原来的无版本号文件,可以在启动时启用升级行为,再定期部署新对象版本。这个组合基于 AWS startup script 和 pip 的环境变量机制,需要在目标 MWAA 环境中验证。AWS 并不保证它适用于任意依赖组合。

1. 在 startup script 中设置 pip 升级选项

startup script 在各 Airflow 组件启动时执行,早于 requirements 安装。可以配置:

#!/bin/sh
export PIP_UPGRADE=1

PIP_UPGRADE 对应 pip 的 --upgrade 选项。配置后,应通过安装日志确认后续 pip 进程确实采用了该设置。升级仍受 constraints 限制,已运行的环境也不会因此定时检查 PyPI。AWS startup script 文档、pip 升级选项

不要把 --upgrade 或 --force-reinstall 直接写成 requirements.txt 中的独立行。requirements 文件只支持部分 pip 选项,这两个选项不在其支持列表中。requirements 文件格式

2. 上传内容相同的新 S3 对象版本,再更新环境

无需改动 requirements.txt 的正文。对于启用了版本控制的 bucket,再次上传相同内容也可以获得新的对象版本,然后将该版本明确提交给 MWAA。

下面的 Python 示例只展示上传和提交更新。使用时请替换 bucket、环境名和对象路径,并配置对应的 AWS Region 与凭证:

from pathlib import Path

import boto3

bucket = "your-mwaa-bucket"
key = "requirements.txt"
environment_name = "your-mwaa-environment"

s3 = boto3.client("s3")
mwaa = boto3.client("mwaa")

uploaded = s3.put_object(
    Bucket=bucket,
    Key=key,
    Body=Path("requirements.txt").read_bytes(),
)

version_id = uploaded.get("VersionId")
if not version_id or version_id == "null":
    raise RuntimeError("S3 bucket must have versioning enabled")

mwaa.update_environment(
    Name=environment_name,
    RequirementsS3Path=key,
    RequirementsS3ObjectVersion=version_id,
)

print(f"Submitted requirements version: {version_id}")

这里传入的是对象 key,不是完整的 s3:// URL;bucket 应与环境配置的源 bucket 一致。版本参数的含义见 UpdateEnvironment API。

把这段逻辑放入定时 CI/CD 作业,就不需要手动反复编辑文件。如果文件只保存在 S3,作业可以先下载当前指定版本,再重新上传。

不要假设重复提交同一个 VersionId 就能强制重装:文档没有将其定义为专门的依赖刷新接口。

3. 跟踪更新结果

UpdateEnvironment 返回成功只表示请求已提交。自动化流程还应等待环境更新结束,检查状态和安装日志,并记录实际安装的版本。

同一环境的更新应串行执行。还需确认安装阶段能够访问 PyPI、constraints 地址或配置的私有包源。

长期使用:让 CI 自动生成版本清单

如果希望更新可复现,更合适的方式是维护一份长期不变的包名清单,由 CI 定期解析依赖、验证兼容性,再生成带版本号的部署文件。

建议流程为:

  1. 在与目标 MWAA 对应的 Airflow、Python 环境和 constraints 下解析候选版本。
  2. 检查依赖冲突,执行必要的 DAG 导入和功能验证。
  3. 生成版本清单,上传到 S3,并提交新的 VersionId。
  4. 等待更新完成,保留上一次可用文件版本,供失败时恢复。

这样无需人工逐个修改版本号,也能知道每次部署使用了哪些版本。AWS 文档建议在本地匹配环境中测试依赖,并为包指定版本,以避免未来的破坏性更新自动进入环境。AWS 依赖管理建议

startup script 可以用于启动阶段的配置,但不会在包发布时自动触发。对于需要持续更新的环境,仍应由外部调度或 CI/CD 控制更新节奏,不要依赖组件何时重启来维持依赖一致性。

备注:内容仅供参考。