You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pandas DataFrame通过for循环追加数据失效问题求助

问题:循环追加数据后Pandas DataFrame始终为空的原因与解决办法

你遇到的是Pandas使用中非常典型的误区——代码里的modified_schemadf.append(...)看似在往DataFrame里加数据,但实际上根本没改变原对象,这是由append方法的特性直接导致的。

核心原因

Pandas的DataFrame.append()是无状态方法:它不会直接修改调用它的原DataFrame,而是返回一个包含追加后数据的新DataFrame对象。你的代码里只是调用了append,但没有把返回的新对象重新赋值给modified_schemadf,所以初始的空DataFrame一直没被更新,最后打印自然还是空的。

快速修复方案

把循环里的append语句改成赋值形式,让modified_schemadf指向追加后的新对象:

modified_schemadf = modified_schemadf.append(redshift_to_pandas("select '"+all_schema[i]+"' as columns_name,(select exists ( select distinct table_schema from information_schema.tables where table_schema like '%"+all_schema[i]+"')) as status",mechanism='append'))

不过要注意:从Pandas 2.0版本开始,append方法已经被标记为弃用,官方更推荐使用pd.concat()来实现数据合并,所以下面的优化方案更值得采用。

更优的实现方式(推荐)

频繁调用append会产生大量临时DataFrame,效率较低。建议先把每次查询得到的小DataFrame收集到列表里,最后一次性合并:

def redshift_to_pandas(sql_query,**kwargs): 
    # pass a sql query and return a pandas dataframe
    cur.execute(sql_query)
    columns_list = [desc[0] for desc in cur.description]
    data = pd.DataFrame(cur.fetchall(),columns=columns_list)
    return data

# Input:这里优化一下,[('backup')]其实等价于['backup'],如果要定义元组元素应该写成[('backup',)]
all_schema = ['backup']

# Loop
try:
    if len(all_schema) == 0:
        raise inputError("The Input has no schema selected. EXITING")
    else:
        # 初始化列表存储所有子DataFrame
        df_list = []
        for schema in all_schema:
            # 用f-string简化字符串拼接(后续建议替换为参数化查询)
            df = redshift_to_pandas(f"select '{schema}' as columns_name,(select exists ( select distinct table_schema from information_schema.tables where table_schema like '%{schema}%')) as status",mechanism='append')
            df_list.append(df)
        # 一次性合并所有子DataFrame,ignore_index重置索引避免重复
        modified_schemadf = pd.concat(df_list, ignore_index=True)
        print(modified_schemadf)
except inputError as e:
    print(e.message)
    logger.error("UNEXPECTED INPUT FOUND, Please check the I/P List . EXITING")
    print(modified_schemadf)

额外优化建议

  1. 避免SQL字符串拼接:直接把变量拼到SQL语句里存在SQL注入风险,建议使用参数化查询。如果你的Redshift连接用的是psycopg2,可以修改函数支持参数:
def redshift_to_pandas(sql_query, params=None, **kwargs): 
    cur.execute(sql_query, params or ())
    columns_list = [desc[0] for desc in cur.description]
    data = pd.DataFrame(cur.fetchall(),columns=columns_list)
    return data

# 调用时传入参数
df = redshift_to_pandas(
    "select %s as columns_name,(select exists ( select distinct table_schema from information_schema.tables where table_schema like %s)) as status",
    params=(schema, f"%{schema}%"),
    mechanism='append'
)
  1. 批量查询代替循环:可以把所有schema一次性传入SQL,用批量查询替代循环调用,效率会更高:
# 生成schema的占位符
schema_strings = ','.join([f"'{s}'" for s in all_schema])
# 一次性查询所有schema的状态
sql = f"""
select s.schema_name as columns_name,
       exists (select 1 from information_schema.tables where table_schema like '%' || s.schema_name || '%') as status
from (values {schema_strings}) as s(schema_name)
"""
modified_schemadf = redshift_to_pandas(sql, mechanism='append')

这样不需要循环,一次查询就能得到所有结果,代码更简洁,性能也更好。


内容的提问来源于stack exchange,提问作者Golokesh Patra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 00:07:44