使用Python调用Athena获取表DDL,如何访问S3查询结果?
解决方案
一、正确读取S3查询结果文件
urllib3不支持直接访问s3://协议的链接,这是你报错的核心原因。可以用AWS官方SDK或awswrangler封装的方法读取S3文件:
方法1:用boto3解析并读取S3对象
先拆分S3路径的桶名和对象键,再通过S3客户端获取内容:
import boto3 # 解析S3路径 s3_path = res['ResultConfiguration']['OutputLocation'] bucket_name = s3_path.split('s3://')[1].split('/')[0] object_key = '/'.join(s3_path.split('s3://')[1].split('/')[1:]) # 读取文件内容 s3_client = boto3.client('s3') response = s3_client.get_object(Bucket=bucket_name, Key=object_key) content = response['Body'].read().decode('utf-8') print(content)
方法2:用awswrangler直接读取S3文本
awswrangler封装了S3操作,一行代码即可完成读取:
import awswrangler as wr s3_path = res['ResultConfiguration']['OutputLocation'] content = wr.s3.read_text(s3_path) print(content)
二、更简便的Athena DDL获取方案
你当前手动调用查询+等待的方式不够高效,awswrangler的read_sql_query函数可以直接执行查询并等待结果返回,无需手动处理查询ID和sleep:
import boto3 import awswrangler as wr boto3.setup_default_session(region_name="us-east-1") # 注意:show create table的表名不需要单引号,若表名含特殊字符用反引号`包裹 sql = "show create table table-name" # 直接获取查询结果DataFrame df = wr.athena.read_sql_query(sql=sql, database='database-name') # 提取DDL内容 ddl = df['create_table_statement'][0] print(ddl)
三、更高效的方式:直接通过Glue获取表元数据
Athena的表元数据存储在AWS Glue Data Catalog中,直接用Glue客户端获取表结构,无需发起Athena查询,速度更快:
import boto3 glue_client = boto3.client('glue', region_name='us-east-1') response = glue_client.get_table(DatabaseName='database-name', Name='table-name') # 拼接生成DDL table = response['Table'] storage_desc = table['StorageDescriptor'] ddl = f"CREATE EXTERNAL TABLE `{table['Name']}` (" for col in storage_desc['Columns']: ddl += f"\n `{col['Name']}` {col['Type']}," ddl = ddl.rstrip(',') + "\n)" ddl += f"\nROW FORMAT SERDE '{storage_desc['SerdeInfo']['SerializationLibrary']}'" ddl += f"\nLOCATION '{storage_desc['Location']}'" # 若表有分区、参数等信息,可按需补充到DDL中 print(ddl)
额外提示:你原SQL中的'table-name'用了单引号,这会被Athena识别为字符串而非表名,需要去掉单引号;若表名包含特殊字符(如空格、连字符),改用反引号`包裹。
内容的提问来源于stack exchange,提问作者freshman_2021
相关产品推荐
相关产品推荐

