来自 pandas read_sql 的 "TypeError: 'NoneType' object is not iterable" 错误

5
我正在尝试在Python中使用pyodbc运行SQL命令。其中SQL命令包含多个SELECT命令和IF语句。
但是我收到以下错误:
columns = [col_desc[0] for col_desc in cursor.description]
TypeError: 'NoneType' object is not iterable

import pyodbc
import pandas as pd
conn = pyodbc.connect("DRIVER={SQL Server};"
                "SERVER=server_name;"
                "DATABASE=master;"
                "Trusted_Connection=yes;")
cursor = conn.cursor()
script="""

If object_id ('tempdb..#Temp1')is not null
drop table #Temp1
Select distinct  a1.some_ID into #Temp1
from DOC.dbo.Document_tbl (NOLOCK)a1
from #Temp1 a1
If object_id ('tempdb..#Temp2')is not null
Drop table #Temp2
select distinct v2.some_data
into #Temp2 from tbl_name (nolock) v2 

If object_id ('tempdb..#Results')is not null
drop table #Results
select distinct a1.*,b1.####
into #Results
from #Temp1 a1
left join #Temp2 b1 on a1.## = b1.##
Select * from #Results
"""

df = pd.read_sql(script, cnxn)
writer = pd.ExcelWriter('result.xlsx')
df.to_excel(writer, sheet_name ='bar')
writer.save()

1
错误显示光标中没有内容,基本上意味着您没有返回任何内容。 - vb_rises
请删除那些 NOLOCK 查询提示,除非您确切地了解为什么需要它们以及使用它们的风险,包括检索无效数据和不存在的数据。 - alroc
谢谢Gord Thompson。 - m.gibin
2个回答

5

包含多个SQL语句的SQL命令文本称为匿名代码块。匿名代码块可以返回多个结果,其中每个结果可以是:

  • 行计数,
  • 包含零个或多个数据行的结果集,或者
  • 错误。

以下示例失败...

sql = """\
SELECT 1 AS foo INTO #tmp;
SELECT * FROM #tmp;
"""
df = pd.read_sql_query(sql, cnxn)
# TypeError: 'NoneType' object is not iterable

...因为首个 SELECT ... INTO 返回的是行数,然后才是第二个 SELECT 返回其结果集。

解决方法是在匿名代码块中加入 SET NOCOUNT ON;,以抑制返回行数,仅返回结果集:

sql = """\
SET NOCOUNT ON;
SELECT 1 AS foo INTO #tmp;
SELECT * FROM #tmp;
"""
df = pd.read_sql_query(sql, cnxn)
# no error

3

对于仍然遇到此错误的其他用户,我发现对于一些语句(聚合空值的窗口函数),我还需要包含SET ANSI_WARNINGS OFF;


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接