Python:将带有Pandas的SQL结果读入要在for循环中使用的列表时出现问题

2024-05-17 10:17:49 发布

您现在位置:Python中文网/ 问答频道 /正文

我是Python新手

我有两个SQL视图

DBOP4和DBOP4_选择

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

DBOP4_选择:

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 = ('1258','1278','1290') 剧本成功了

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

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

如果有人能帮我解决问题,我会很高兴


Tags: fromsqlserverconnqueryselectpdprint
1条回答
网友
1楼 · 发布于 2024-05-17 10:17:49

当前,for循环(for sachbearbeiternr in Sachbearbeiternummer)在数据帧的列之间迭代,然后将这些列传递到查询中,而不使用引号括住文本值。这就是为什么错误指向第一个列名SNBR,作为无效名称

一个直接的解决方法是在数据帧的特定列(或系列)上循环,然后使用^{}params参数化查询的值。顺便说一下,不需要在read_sql_query之后调用DataFrame,因为文档表明方法的返回值是DataFrame。另外,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))

相关问题 更多 >