CDATA SharePoint Python连接器read_sql chunksize不支持致数据重复
问题描述
基于CDATA连接驱动,使用pandas的read_sql()与to_sql()方法操作SharePoint列表时出现记录数异常,具体现象如下:
- 建立连接后分块读取源列表数据,写入结构完全一致的目标SharePoint列表时,目标列表记录数不符合预期
- 一次性完成全量读写操作时,源列表与目标列表的记录数完全一致
- 循环传入
chunksize参数分块读取写入时,目标列表记录数远高于源数据,且无固定重复比例:例如3万条的源列表最终会生成5万条目标记录
参考文档:CDATA Python Connector for SharePoint 官方文档
复现代码如下:
def add_df_to_spol_list(df, listname, con, index=False): df.to_sql(listname, con=con, if_exists="append", index=index) # 分块读取源DataFrame时结果异常 sql = "SELECT * from [" + prod_list_name + "]" for chunk in pd.read_sql(sql, prod_engine_spol, chunksize=100): add_df_to_spol_list(df=chunk, listname=dev_list_name, con=dev_engine_spol)
核心疑问:CDATA连接器是否不兼容pandas的分块读取协议?
问题原因
该问题不属于pandas分块读取协议兼容性问题,本质是CDATA SharePoint驱动的默认分页逻辑与pandas分块读取的游标逻辑存在冲突:
- pandas指定
chunksize调用read_sql时,会依赖驱动返回的可滚动游标,按固定偏移量逐批拉取数据 - CDATA驱动对接SharePoint REST API时,默认使用内置分页逻辑拉取列表数据,不会为查询保留固定数据快照:分块拉取过程中如果驱动内部分页游标没有和pandas传入的偏移参数正确对齐,就会重复拉取同一段数据,写入后产生重复记录,最终总条数远高于源数据
- 全量读取时驱动会一次性走完所有内置分页流程,内部游标不会重置错位,因此不会出现数据重复问题。
解决方案
可通过以下两种方式规避该问题:
- 调整驱动连接参数对齐分页步长
初始化CDATA连接时在连接串中添加SupportSQLPaging=true参数,同时设置PaginationSize参数值和代码中chunksize值保持一致,让驱动的分页步长和pandas分块步长完全对齐,避免游标错位。 - 手动控制分页查询逻辑
不依赖pandas的chunksize参数自动分块,自行在循环中编写带LIMIT和OFFSET的SQL语句逐批拉取数据,每批拉取完成后手动更新偏移量,从根源上避免驱动内部游标错位,示例代码如下:chunk_size = 100 offset = 0 while True: sql = f"SELECT * FROM [{prod_list_name}] LIMIT {chunk_size} OFFSET {offset}" chunk = pd.read_sql(sql, prod_engine_spol) if len(chunk) == 0: break add_df_to_spol_list(df=chunk, listname=dev_list_name, con=dev_engine_spol) offset += chunk_size
注意:如果SharePoint列表数据量超过5万条,需要提前为列表中查询排序用到的字段添加索引,避免OFFSET查询触发SharePoint列表阈值限制报错。
内容的提问来源于stack exchange,提问作者smackenzie
相关产品推荐
相关产品推荐

