技术问题求助:CodeBuild通过Poetry发布至AWS CodeArtifact报UploadError失败,以及Databricks中Delta数据集周期性导入时如何直接替换现有数据
我来帮你逐个解决这两个问题:
下面是几种常见的排查和解决思路,你可以按顺序尝试:
检查CodeBuild角色的权限配置
确保CodeBuild使用的服务IAM角色拥有CodeArtifact的必要操作权限,至少需要包含codeartifact:GetRepositoryEndpoint、codeartifact:PutPackageVersions、codeartifact:PublishPackageVersion这几个权限。你可以在IAM控制台给该角色添加类似这样的自定义策略:{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "codeartifact:GetRepositoryEndpoint", "codeartifact:PutPackageVersions", "codeartifact:PublishPackageVersion", "codeartifact:GetAuthorizationToken" ], "Resource": "arn:aws:codeartifact:<region>:<account-id>:repository/<domain>/<repo-name>" } ] }验证Poetry的仓库端点配置
确认你在CodeBuild构建过程中配置的CodeArtifact端点正确,端点格式应为https://<domain>-<account-id>.d.codeartifact.<region>.amazonaws.com/pypi/<repo-name>/。可以在构建脚本里显式设置:poetry config repositories.my-codeartifact-repo https://<your-domain>-<your-account-id>.d.codeartifact.<your-region>.amazonaws.com/pypi/<your-repo>/确保身份认证有效
CodeBuild需要先获取CodeArtifact的授权令牌,然后传递给Poetry。在构建脚本里添加以下命令来设置认证:# 获取授权令牌,有效期12小时 CODEARTIFACT_TOKEN=$(aws codeartifact get-authorization-token --domain <your-domain> --domain-owner <your-account-id> --query authorizationToken --output text) # 设置Poetry的HTTP Basic认证 poetry config http-basic.my-codeartifact-repo aws $CODEARTIFACT_TOKEN注意这里的仓库名(
my-codeartifact-repo)要和你之前配置的一致。检查包版本是否重复
UploadError也可能是因为你要发布的包版本已经存在于CodeArtifact仓库中。你可以登录CodeArtifact控制台确认版本情况,如果允许跳过已存在版本,可以在poetry publish命令后加上--skip-existing参数:poetry publish -r my-codeartifact-repo --skip-existing查看详细错误日志
建议在构建脚本里使用poetry publish -vvv来输出 verbose 日志,这样能看到更具体的错误细节(比如网络问题、包文件损坏等),帮助你精准定位问题。
你完全不需要手动删除路径,Delta Lake本身提供了多种覆盖数据的方式,比删除再保存更高效:
全量覆盖整个数据集
只需要在写入时添加mode("overwrite")参数,就会直接替换目标路径下的所有Delta数据和元数据:df.write.format("delta").mode("overwrite").save("dbfs:/mnt/defaultDatalake/datasets/datasources")覆盖数据同时更新表结构
如果你的新DataFrame和原有数据集的schema不一致(比如新增/删除列、修改列类型),可以加上overwriteSchema参数,这样会在覆盖数据的同时更新表结构:df.write.format("delta")\ .mode("overwrite")\ .option("overwriteSchema", "true")\ .save("dbfs:/mnt/defaultDatalake/datasets/datasources")条件覆盖部分数据(可选)
如果你不需要全量替换,只想覆盖满足特定条件的数据,可以使用replaceWhere参数,这样只会替换符合条件的分区或行,效率更高:df.write.format("delta")\ .mode("overwrite")\ .option("replaceWhere", "data_date = '2024-05-20'")\ .save("dbfs:/mnt/defaultDatalake/datasets/datasources")
内容的提问来源于stack exchange,提问作者alonisser

