Python:将带有pandas的SQL结果读取到用于for循环的列表中时出现问题

Posted

技术标签:

【中文标题】Python:将带有pandas的SQL结果读取到用于for循环的列表中时出现问题【英文标题】:Python: Problem reading SQL results with pandas into list to be used in for loop 【发布时间】:2020-07-04 14:46:36 【问题描述】:

我是 Python 新手。

我有两个 SQL 视图。

DBOP4 和 DBOP4_SELECTION

DBOP4 包含许多列和许多行。 DBOP4 的一列是 SaBeNummerDebitoren。

DBOP4_SELECTION:

SELECT        SaBeNummerDebitoren AS SBNr, [Sachbearbeiter Debitoren] AS SBName
FROM            dbo.DBOP4
GROUP BY SaBeNummerDebitoren, [Sachbearbeiter Debitoren]

我尝试编写一个 python 脚本,输出 DBOP4 的结果,为 SaBeNummerDebitoren 中的每个现有值分开。

import pandas as pd
import pyodbc 
conn = pyodbc.connect('Driver=SQL Server;'
                      'Server=***;'
                      'Database=***;'
                      'Trusted_Connection=yes;')

cursor = conn.cursor()
 
SQL_SBNR_Selection = pd.read_sql_query('SELECT SBNR FROM DBOP4_SBSELECTION' ,conn)
print(SQL_SBNR_Selection)
#print(type(SQL_SBNR_Selection))

#Sachbearbeiternummer = ('1258','1278','1290')
Sachbearbeiternummer = pd.DataFrame(SQL_SBNR_Selection)

for sachbearbeiternr in Sachbearbeiternummer:
    print("Starte " + str(sachbearbeiternr))
    sql_query = pd.read_sql_query('SELECT *  FROM DBOP4 Where [SaBeNummerDebitoren] =' +str(sachbearbeiternr) ,conn)
    print(sql_query)
    print(type(sql_query))

    df = pd.DataFrame(sql_query)

    df.to_excel (r'C:\OP\export_dataframe '+str(sachbearbeiternr)+'.xlsx', sheet_name='DBOP4_' +str(sachbearbeiternr) , index = False, header=True, freeze_panes=(1,5))
      

print("Fertig")

输出如下:

     SBNR
0  1258.0
1  1278.0
2  1290.0
Starte SBNR

调试信息:

Exception has occurred: DatabaseError
Execution failed on sql 'SELECT *  FROM DBOP4 Where [SaBeNummerDebitoren] =SBNR': ('42S22', "[42S22] [Microsoft][ODBC SQL Server Driver][SQL Server]Ungültiger Spaltenname 'SBNR'. (207) (SQLExecDirectW)")
  File "C:\AzureDevopsRepos\Python Skripte\PythonApplication1\PythonApplication1.py", line 20, in <module>
    sql_query = pd.read_sql_query('SELECT *  FROM DBOP4 Where [SaBeNummerDebitoren] =' +str(sachbearbeiternr) ,conn)

问题: for 循环不会对列表中的每个数字('1258'、'1278'、'1290')重复 excel 导出。

当我确实像这样填充 Sachbearbeiternummer Sachbearbeiternummer = ('1258','1278','1290') 该脚本有效。

问题 1: 循环以列 SBNR 的名称而不是第一个值开始。

问题 2: 尝试使用 SBNR 后循环不会继续。 如果我只是在 for 循环中执行 print("Starte " + str(sachbearbeiternr)),它也会在 SBNR 之后停止。

如果有人能帮我解决我的问题,我会很好。

【问题讨论】:

【参考方案1】:

目前,您的 for 循环 (for sachbearbeiternr in Sachbearbeiternummer) 遍历数据框的列,然后您将其传递到查询中,而不用引号括住文字值。这就是错误将第一列名称SNBR 指向无效名称的原因。

一个直接的解决方法是遍历数据框的特定列(或系列),然后使用 read_sql_queryparams 参数将查询参数化。顺便说一句,没有必要在read_sql_query 之后调用DataFrame,因为文档表明方法的返回值是DataFrame。另外,Pandas-SQL 操作不需要游标。

# ITERATE ACROSS COLUMN OR SERIES
for sachbearbeiternr in Sachbearbeiternummer['SBNR']:
    print("Starte " + str(sachbearbeiternr))
    ...
    # BIND ITERATOR VALUE AS PARAMETER
    sql_query = pd.read_sql_query('SELECT * FROM DBOP4 WHERE [SaBeNummerDebitoren] = ?',
                                  conn, params = [sachbearbeiternr])
    

话虽如此,不需要第二个查询或数据框。只需导入 整个 视图,然后运行 ​​Pandas 的 groupby() 以通过 SaBeNummerDebitoren 的不同值拆分数据框。从那里,迭代和处理每个子集。

df_DBOP4 = pd.read_sql_query('SELECT *  FROM DBOP4', conn)

# SPLIT DATA FRAME BY COLUMN: i IS SPLIT VALUE, g IS SUBSET DF
for i,g in df_DBOP4.groupby(['SaBeNummerDebitoren']):
    print("Starte " + str(i))        
    print(g.head(10))           # FIRST 10 ROWS

    df.to_excel(r'C:\OP\export_dataframe 0.xlsx'.format(i), 
                sheet_name='DBOP4_'+str(i), index = False, 
                header=True, freeze_panes=(1,5))

【讨论】:

以上是关于Python:将带有pandas的SQL结果读取到用于for循环的列表中时出现问题的主要内容,如果未能解决你的问题,请参考以下文章

如何将带有文本信息的 1.3 GB csv 文件读入 Python 的 pandas 对象?

以科学记数法将带有科学记数法的文本文件读取到 pandas 数据框

将外部 SQL 文件读入 Pandas 数据框

python:pandas - 如何将前两行 pandas 数据帧组合到数据帧头?

Python Pandas - 读取带有注释标题行的 csv

利用pandas将mysql查询出得结果写入到excel文件