【问题标题】:TypeError: 'type' object is not subscriptable with pypyodbc (Python)TypeError: 'type' 对象不能用 pypyodbc (Python) 下标
【发布时间】:2016-06-28 12:58:37
【问题描述】:

我下面的 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

【问题讨论】:

    标签: python sql-server pypyodbc


    【解决方案1】:

    我认为是因为您在以下位置有一个空列表:

    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:

    如果参数是用户输入数据,则先前提出的解决方案会暴露于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))
    

    如果你有多个参数:

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

    【讨论】:

    • 感谢您的回答!我试图删除空列表和同样的问题!我用新的代码编辑我的代码
    • @amiraayadi ,删除这一行:log=tuple(log) 并将cursor.execute(SQLCommand,(log,)) 修改为cursor.execute(SQLCommand, log)
    • 'SQL 包含 1 个参数标记,但提供了 3 个参数')
    • 如果我进行此更改:SQLCommand = ("select count(*) from PRODUCTION where ID_TV IN (?,?,?)") 它可以工作,但在我的真实列表中,我处理 [[ 1,2,3],[1,2]] 不是同一个 len 所以我不能使用 "in (?,?,?)"
    • 那么params的长度是可变的不固定的?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-14
    • 2023-03-20
    • 2015-07-31
    • 2020-02-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多