如何在字典推导式中通过f-string传参为schema下每张表生成DataFrame
失败原因
f-string的特性是定义时立即求值,你在全局作用域提前定义query_table这个f-string时,循环变量table还不存在,也无法和后续字典推导式里的循环变量做绑定,因此f-string会在定义阶段就抛出变量未定义的错误,就算不报错也只会读取定义时table的固定值,无法动态跟随循环变化。
解决方案
方案1:将f-string移入推导式内部
直接在字典推导式的循环逻辑中定义查询字符串,此时每次循环的表名变量name处于可用状态,f-string可以正确读取当前迭代的表名完成拼接:
query = """ SELECT * FROM information_schema.tables WHERE table_schema = 'my_schema' """ my_tables = pd.read_sql_query(query, conn) tables = [x for x in my_tables.table_name] tables_res = { name: pd.read_sql_query( f""" SELECT * FROM my_schema.{name} limit 5 """, conn ) for name in tables }
方案2:预先定义字符串模板,循环时传参
如果需要提前抽离SQL模板方便复用,可以不使用f-string,改用普通字符串带占位符的形式,循环时调用format方法传入当前表名:
query = """ SELECT * FROM information_schema.tables WHERE table_schema = 'my_schema' """ # 此处不加f前缀,用{table}作为表名占位符 query_table_tpl = """ SELECT * FROM my_schema.{table} limit 5 """ my_tables = pd.read_sql_query(query, conn) tables = [x for x in my_tables.table_name] tables_res = {name: pd.read_sql_query(query_table_tpl.format(table=name), conn) for name in tables}
注意事项
- 直接将表名拼接入SQL存在SQL注入风险,如果表名来源是外部不可信输入,需要提前校验表名是否属于从
information_schema查询到的合法表名列表。 - 你原本封装为函数的写法可读性更高,适合SQL逻辑复杂、需要多处复用的场景。
内容的提问来源于stack exchange,提问作者Jonas Palačionis
相关产品推荐
相关产品推荐

