如何自动将SQL Server查询结果中的UUID转为字符串导出Parquet文件
问题原因
报错的核心原因是pyarrow写入Parquet时无法识别Python原生的uuid.UUID类型对象,你通过pymssql读取SQL Server的uniqueidentifier类型字段时,返回值会被自动转为Python的UUID对象,存储在object类型列中导致转换失败。
解决方案
方案1:DataFrame层面自动转换(通用所有数据库场景)
该方案不需要手动指定UUID列,自动扫描所有object类型列,通过少量样本判断是否为UUID列后批量转字符串,适配不同查询的动态列结构:
import pandas as pd import sqlalchemy as sal import uuid def auto_convert_uuid_cols(df): # 仅扫描object类型列,其他类型列不可能存储UUID对象 for col in df.select_dtypes(include=["object"]).columns: # 取前100个非空值做判断,避免全量扫描影响性能 sample = df[col].dropna().head(100) if len(sample) == 0: continue # 验证样本是否均为UUID类型 if all(isinstance(val, uuid.UUID) for val in sample): df[col] = df[col].apply(lambda x: str(x) if x is not None else None) return df def sql_to_parquet(query, connection_string, output_file): engine = sal.create_engine(connection_string) with engine.connect() as conn: df = pd.read_sql(query, con=conn) # 自动转换所有UUID列 df = auto_convert_uuid_cols(df) df.to_parquet(output_file)
方案2:SQLAlchemy层面类型适配(SQL Server专用,性能更高)
该方案直接在数据库驱动层面对uniqueidentifier类型做映射,读取时直接返回字符串,不需要后续对DataFrame做二次处理,性能更优:
import pandas as pd import sqlalchemy as sal from sqlalchemy import TypeDecorator from sqlalchemy.dialects.mssql import UNIQUEIDENTIFIER class UUIDToString(TypeDecorator): impl = UNIQUEIDENTIFIER cache_ok = True def process_result_value(self, value, dialect): return str(value) if value is not None else None def sql_to_parquet(query, connection_string, output_file): # 注册类型映射,将uniqueidentifier返回值直接转为字符串 engine = sal.create_engine( connection_string, type_map={UNIQUEIDENTIFIER: UUIDToString} ) with engine.connect() as conn: df = pd.read_sql(query, con=conn) df.to_parquet(output_file)
内容的提问来源于stack exchange,提问作者Chris Wood
相关产品推荐
相关产品推荐

