Azure Python SDK Storage Table备份报TableNotFound错误及分页查询问题
问题根因
核心错误是源表名和目标表名参数混用:
你在循环中生成的table = tb.name + today是目标存储的表名,调用queryAndSaveAllDataBySize时将该值作为第一个参数传入。递归逻辑中直接用这个参数查询源存储table_out的表,但源存储中不存在带today后缀的表,因此触发TableNotFound报错。
刚好你的表单数据量为100行,和query_size配置一致:Azure Table SDK在返回结果数量等于请求的num_results时,无论后续是否还有数据都会返回延续令牌,需要下一次请求确认是否存在剩余数据,因此第一次查询后就进入递归逻辑触发错误。
修复方案
1. 分离源表、目标表参数
修改递归函数的参数定义,把源表名和目标表名拆分为两个独立参数,避免混用,修改后代码如下:
query_size = 100 # 新增参数source_tb_name为源存储表名,target_tb_name为目标存储表名 def queryAndSaveAllDataBySize(source_tb_name: str, target_tb_name: str, resp_data: ListGenerator, table_out: TableService, table_in: TableService, query_size: int): for item in resp_data: # remove etag and Timestamp appended by table service del item.etag del item.Timestamp print(f"insert data: {str(item)} into table: {target_tb_name}") table_in.insert_or_replace_entity(target_tb_name, item) if resp_data.next_marker: # 查询源存储时使用源表名 data = table_out.query_entities(table_name=source_tb_name, num_results=query_size, marker=resp_data.next_marker) queryAndSaveAllDataBySize(source_tb_name, target_tb_name, data, table_out, table_in, query_size) tbs_out = table_service_out.list_tables() print(tbs_out) for tb in tbs_out: source_tb = tb.name target_tb = tb.name + today print(target_connection_string) # create table with same name in storage2 table_service_in.create_table(table_name=target_tb, fail_on_exist=False) # first query data = table_out.query_entities(source_tb, num_results=query_size) # 传入分开的源、目标表名 queryAndSaveAllDataBySize(source_tb, target_tb, data, table_service_out, table_service_in, query_size)
2. 可选:一次性加载全量数据
如果不需要自定义分页逻辑,可以直接将query_entities的num_results参数设为None,SDK会自动处理延续令牌拉取全量数据,无需自己实现递归分页:
# 单表全量数据拉取示例 all_data = table_out.query_entities(source_tb, num_results=None) for item in all_data: # 后续写入逻辑和之前一致
3. 额外优化建议
- 可增加单个表的异常捕获逻辑,避免单表处理失败导致整个备份任务终止
- 可对已完成备份的表做标记,避免脚本异常中断后重复备份全量表
内容的提问来源于stack exchange,提问作者Nayden Van
相关产品推荐
相关产品推荐

