使用S3 Select提取S3上Parquet文件列时遇ParseSelectMissingFrom错误
问题分析与解决方案
错误根源
从你的输出可以看到,生成的SQL是:
SELECT 01A450012-5-1767-474-256-256 FROM s3object s WHERE s.key = 'my-folder/01A450012.parquet'
这里存在两个致命问题:
- 列名解析错误:
01A450012-5-1767-474-256-256被SQL解析器当成了连续减法运算(比如01A450012 -5 -1767 ...),导致解析器认为SELECT子句的表达式未完成,触发ParseSelectMissingFrom错误。这是因为代码错误地用str(idx)代替cols生成查询列。 - 多余的WHERE条件:当你通过
Key参数指定单个文件时,不需要WHERE s.key = '{key}'——这里的s.key是针对前缀批量查询时过滤S3对象的字段,而非Parquet文件内的列。你的Parquet数据里大概率没有key这个列,即便语法正确,后续也会报列不存在的错误。
修复后的代码
修正查询逻辑,确保始终使用cols指定要提取的列,同时移除多余的WHERE条件:
s3 = boto3.client('s3') s3_uri = 's3://my-bucket/my-folder/' bucket, prefix = s3_uri[5:].rstrip('/').split('/', 1) key = f"{prefix}/{idx.split('-')[0]}.parquet" cols = ['col1', 'col2'] # 处理cols为单个字符串或列表的情况 cols_str = ', '.join(cols) if isinstance(cols, list) else cols # 移除多余的WHERE条件,直接查询指定文件的列 query = f"SELECT {cols_str} FROM s3object s" print(bucket, prefix) print(key) print(query) response = s3.select_object_content( Bucket=bucket, Key=key, ExpressionType='SQL', Expression=query, InputSerialization={'Parquet': {}}, OutputSerialization={'JSON': {}} ) data = ''.join( event['Records']['Payload'].decode() for event in response['Payload'] if 'Records' in event ) df = pl.read_json(io.StringIO(data), lines=True)
额外说明
- 如果
cols需要动态替换,要确保最终列名符合SQL语法:比如列名包含特殊字符时,要用双引号包裹(例如SELECT "01A450012-5-1767-474-256-256" FROM s3object s)。 - 若要批量查询某个前缀下的多个Parquet文件,才需要使用
WHERE s.key LIKE 'prefix/%'这类条件,此时需将Key参数替换为Prefix参数(注意API参数差异)。
内容的提问来源于stack exchange,提问作者DanielBell99
相关产品推荐
相关产品推荐

