2016-06-28 30 views
0

我的下面的python代碼有什麼問題?TypeError:'type'對象不可用pypyodbc(Python)進行自定義

我想連接到我的數據庫,選擇一些信息。這些都是在列表的名單,我搶單,我做了一個「select..from..where..IN」:

import pypyodbc 
connection = pypyodbc.connect('Driver={SQL Server};' 
            'Server=X;' 
            'Database=Y;' 
            'uid=X;pwd=Y') 
cursor = connection.cursor() 

NbFiche=0 
L=[[4702, 3095, 3543], [2040, 2030, 2020], []] 
for i in range(0,3): 
    log=L[i] 


    if (log is not None): 
     if (len(log)==3):     

      SQLCommand = ("select count(*) from PRODUCTION where ID_TV IN (?) ") 
      cursor.execute(SQLCommand,(log,)) 
      results = cursor.fetchone() 
      NbFiche += results[0] 

這是錯誤:

Traceback (most recent call last): 
     File "//Srvaktct-bur02/telecontact/TCT TRAVAIL/Pôle Fichier/AMIRA/STATISTIQUES/nimp.py", line 18, in <module> 
     cursor.execute(SQLCommand,(log,)) 
     File "C:\Users\admin_fichier\AppData\Local\Programs\Python\Python35\lib\site-packages\pypyodbc-1.3.3-py3.5.egg\pypyodbc.py", line 1470, in execute 
     self._BindParams(param_types) 
     File "C:\Users\admin_fichier\AppData\Local\Programs\Python\Python35\lib\site-packages\pypyodbc-1.3.3-py3.5.egg\pypyodbc.py", line 1275, in _BindParams 
     if param_types[col_num][0] == 'u': 
    TypeError: 'type' object is not subscriptable 

新的代碼(編輯):

import pypyodbc 
connection = pypyodbc.connect('Driver={SQL Server};' 
           'Server=x;' 
            'Database=y;' 
            'uid=x;pwd=y') 

cursor = connection.cursor() 

NbFiche=0 
L=[[4702, 3095, 3543], [2040, 2030, 2020]] 
for log in L: 
    log=tuple(log) # I also tried with a list 

    SQLCommand = ("select count(*) from PRODUCTION where ID_TV IN (?) ") 
    cursor.execute(SQLCommand,(log,)) 
    results = cursor.fetchone() 
    NbFiche += results[0] 

編輯:

import pypyodbc 
connection = pypyodbc.connect('Driver={SQL Server};' 
            'Server=x;' 
             'Database=y;' 
             'uid=x;pwd=y') 
cursor = connection.cursor() 
NbFiche=0 
L=[[4702, 3095], [2040, 2030, 2020]] 
for log in L: 
    SQLCommand = ("select count(*) from PRODUCTION where ID_TV IN (?)") 
    params = ','.join(map(str,log)) 
    cursor.execute(SQLCommand,params) 
    results = cursor.fetchone() 
    NbFiche += results[0] 

以下結果:

Traceback (most recent call last): 
    File "//Srvaktct-bur02/telecontact/TCT TRAVAIL/Pôle Fichier/AMIRA/STATISTIQUES/nimp.py", line 13, in <module> 
    cursor.execute(SQLCommand,params) 
    File "C:\Users\admin_fichier\AppData\Local\Programs\Python\Python35\lib\site-packages\pypyodbc-1.3.3-py3.5.egg\pypyodbc.py", line 1454, in execute 
    raise TypeError("Params must be in a list, tuple, or Row") 
TypeError: Params must be in a list, tuple, or Row 

回答

0

我想是因爲你有一個空列表:

L=[[4702, 3095, 3543], [2040, 2030, 2020], []] 
              ^^ 

而且隨着if測試時,甚至認爲該列表是空的,它通過測試,類似下面的例子:

>>> l = [] 
>>> if l is not None: 
     print('l is not empty') 


l is not empty 

哪項是錯誤的,其實,所以,要解決這個問題,這樣做是:

>>> if l: 
     print('l is not empty') 
    else: 
     print('l is Empty') 


l is Empty 

因此,改變你的測試表達式:

if log: 
    if len(log)==3: 
     #... 

編輯:

如果log長度是可變長的,那麼很可能你必須先構建字符串參數,然後將它傳遞到cursor.execute方法,這種方法:

SQLCommand = "select count(*) from PRODUCTION where ID_TV IN ({}) " 
params = ','.join(map(str,log)) 
cursor.execute(SQLCommand.format(params)) 

EDIT2:

如果params是用戶輸入數據,則先前建議的解決方案會暴露於SQL_injections漏洞。因此,更好的辦法是將它們作爲參數傳遞給cursor.execute方法:

L=[[4702, 3095, 3543], [2040, 2030, 2020]] 
for log in L: 
    if log: 
     SQLCommand = "select count(*) from PRODUCTION where ID_TV IN ?" 
     cursor.execute(SQLCommand, tuple(log)) 

如果您有多個PARAMS:

SQLCommand = "select ?, ? from PRODUCTION where ID_TV IN ?" 
cursor.execute(SQLCommand, (p1, p2, tuple(log))) 
+0

坦克爲您解答! 我試圖刪除空列表和相同的問題! 我用新的編輯我的代碼 – blabla

+0

@amiraayadi,刪除此行:'log = tuple(log)'並修改'cursor.execute(SQLCommand,(log,))'到'cursor.execute(SQLCommand,log) ' –

+0

這裏是新的錯誤: – blabla

相關問題