【问题标题】:sqlite3 error: You did not supply a value for binding 1sqlite3 错误:您没有为绑定 1 提供值
【发布时间】:2020-08-30 10:31:28
【问题描述】:
def save():
    global editor
    conn = sqlite3.connect('address_book.db')

    c = conn.cursor()

    recordID = delete_box.get()

    c.execute("""UPDATE addresses SET
                first_name=:first,
                last_name=:last,
                address=:address,
                city=:city,
                state=:state,
                zipcode=:zipcode

                WHERE oid=:oid""",
                {
                'oid': int(recordID),
                'first:': ef_name.get(),
                'last': el_name.get(),
                'address': eaddress.get(),
                'city': ecity.get(),
                'state': estate.get(),
                'zipcode': ezipcode.get()})

    conn.commit()
    conn.close()
    editor.destroy()

文件“C:/Users/Luke/PycharmProjects/GUI/database.py”,第 23 行,保存 c.execute("""更新地址集 sqlite3.ProgrammingError:您没有为绑定 1 提供值。

任何人都可以看到导致此错误的原因吗?我确定我没有在任何地方打错字,并且很困惑这可能是什么原因。

【问题讨论】:

  • 再看看你的冒号。
  • @Shawn 你能澄清一下吗?
  • @Shawn 抱歉,这是我第一次使用 sqlite3,所以我再次检查,仍然迷路
  • 参数绑定字典中的一个条目与其他条目不同

标签: python-3.x sqlite


【解决方案1】:

错误是由于多余的冒号造成的。替换

'first:': ef_name.get(), 

'first': ef_name.get(),

【讨论】:

    【解决方案2】:

    欢迎来到 StackOverflow!我认为您犯的错误是您使用了参数替代样式(paramstyle),这不是sqlite3 上的默认样式。您正在尝试使用 named 样式而不是默认的 qmark 样式。如果您使用qmark 样式,您的UPDATE 将如下所示:

    c.execute(
        'UPDATE addresses SET first_name=?, last_name=?, address=?, city=?, state=?, zipcode=? WHERE old=?', 
        (ef_name.get(), el_name.get(), eaddress.get(), ecity.get(), 
         estate.get(), ezipcode.get(), int(recordID))
    )
    

    但是如果你真的想使用named 参数样式,你可以为那个模块设置那个属性。这是一个完整的例子:

    import sqlite3
    
    sqlite3.paramstyle = 'named'
    
    parameters = [
        {
            'old': 1,
            'first': "Tony",
            'last': "Starks",
            'address': '10880 Malibu Point',
            'city': 'Malibu',
            'state': 'California',
            'zipcode': '12345-6789'
        },
        {
            'old': 1,
            'first': "Pepper",
            'last': "Potts",
            'address': '10880 Malibu Point',
            'city': 'Malibu',
            'state': 'California',
            'zipcode': '12345-6789'
        }
    ]
    
    
    conn = sqlite3.connect('address_book.db')
    c = conn.cursor()
    
    c.execute('CREATE TABLE addresses (old, first_name, last_name, address, city, state, zipcode)')
    c.execute('INSERT INTO addresses  VALUES (:old, :first, :last, :address, :city, :state, :zipcode)', parameters[0])
    conn.commit()
    
    print('After INSERT')
    for row in c.execute('SELECT * FROM addresses'):
        print(row)
    
    c.execute('UPDATE addresses SET first_name=:first, last_name=:last, address=:address, city=:city, state=:state, zipcode=:zipcode WHERE old=:old', parameters[1])
    conn.commit()
    
    print('After UPDATE')
    for row in c.execute('SELECT * FROM addresses'):
        print(row)
    
    conn.close()
    

    【讨论】:

    • 非常感谢!我为该部分观看的教程使用了名为 paramstyle 并且它适用于他们,所以他们必须在相机之外或在拍摄之前更改 paramstyle。我以为我快疯了,因为我最终一个字母一个字母地复制它,但它仍然没有用!
    • 您没有解释绑定 1 是 oid 并且缺少值。 sqlite3 的错误消息不是很有帮助,我认为这是一个错误,它只按数字而不是按名称。
    • @Wolfgang:就像我在解释中所说,sqlite3 似乎默认使用qmark,您在其中使用元组提供 SQL 查询使用的值。由于 SQL 查询中的参数按照它们在元组中出现的顺序进行匹配,因此错误消息完全有意义,因为 sqlite 只能通过它们在元组中的索引来识别参数。
    • @Wolfgang:因为看起来 Luke Gries 似乎想要使用 named 样式进行参数替换,解决方案是在该模块中的适当全局变量中设置该值 (sqlite3.paramstyle = 'named' )。然后,他可以在查询中使用old=:old 形式,并使用dict 而不是tuple 为其提供值。
    • 任何人都可以看到导致此错误的原因吗?有两个原因:一个是您解释的主要原因,另一个是需要解释哪一列是问题的具体原因。即使软件只能处理数字,也最好用名字来解释原因。
    【解决方案3】:

    为了避免报告为https://bugs.python.org/issue41638 的情况,我正在使用包装器。另请参阅python sqlite insert named parameters or null,了解有关如何存储具有需要映射到不同列的不同键集的字典的更一般问题的解决方案。

    def testBindingError(self):
            '''
            test list of Records with incomplete record leading to
            "You did not supply a value for binding 2"
            see https://bugs.python.org/issue41638
            '''
            listOfRecords=[{'name':'Pikachu', 'type':'Electric'},{'name':'Raichu' }]
            for executeMany in [True,False]:
                try:
                    self.checkListOfRecords(listOfRecords,'Pokemon','name',executeMany=executeMany)
                    self.fail("There should be an exception")
                except Exception as ex:
                    if self.debug:
                        print(str(ex))
                    self.assertTrue('no value supplied for column' in str(ex)) 
    

    导致:

    executeMany:

    INSERT INTO Pokemon (name,type) values (:name,:type)
    failed: no value supplied for column 'type'
    

    没有executeMany:

    INSERT INTO Pokemon (name,type) values (:name,:type)
    failed: no value supplied for column 'type'
    record  #2={'name': 'Raichu'}
    

    包装代码是:

    def store(self,listOfRecords,entityInfo,executeMany=False):
            '''
            store the given list of records based on the given entityInfo
            
            Args:
              
               listOfRecords(list): the list of Dicts to be stored
               entityInfo(EntityInfo): the meta data to be used for storing
            '''
            insertCmd=entityInfo.insertCmd
            try:
                if executeMany:
                    self.c.executemany(insertCmd,listOfRecords)
                else:
                    index=0
                    for record in listOfRecords:
                        index+=1
                        self.c.execute(insertCmd,record)
                self.c.commit()
            except sqlite3.ProgrammingError as pe:
                msg=pe.args[0]
                if "You did not supply a value for binding" in msg:
                    columnIndex=int(re.findall(r'\d+',msg)[0])
                    columnName=list(entityInfo.typeMap.keys())[columnIndex-1]
                    debugInfo=""
                    if not executeMany:
                        if self.errorDebug:
                            debugInfo="\nrecord  #%d=%s" % (index,repr(record))
                    raise Exception("%s\nfailed: no value supplied for column '%s'%s" % (insertCmd,columnName,debugInfo))
                else:
                    raise pe
    

    更多详情见storage/sql.pytests/testSqlite3.py

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-10-05
      • 1970-01-01
      • 1970-01-01
      • 2017-08-19
      • 1970-01-01
      • 2020-12-10
      • 2020-05-09
      相关资源
      最近更新 更多