Python调用API存储数据至SQLite遇ProgrammingError错误求助
解决sqlite3.ProgrammingError: Binding 1 has no name的问题
这个错误的根源很明确:你在SQL语句里用了位置占位符?,但传给execute的参数是一个字典。SQLite的参数绑定规则很严格,占位符类型必须和参数类型匹配:
- 用
?作为占位符时,必须传入元组或列表类型的参数; - 用命名占位符(比如
:Identifier)时,才能传入字典类型的参数。
下面给你两种直接可行的解决方案:
方案1:将字典转为元组/列表,保留位置占位符
如果不想修改SQL语句,只需要把你的to_db字典转换成对应顺序的元组即可。比如假设你的to_db是这样的字典:
to_db = { "Identifier": "BTC", "symbol": "₿", "description": "Bitcoin" }
把它转成和SQL字段顺序一致的元组:
to_db_tuple = (to_db["Identifier"], to_db["symbol"], to_db["description"]) cur.execute("INSERT INTO COINS (Identifier, symbol, description) VALUES (?, ?, ?);", to_db_tuple)
⚠️ 注意:元组里的元素顺序必须和SQL语句中VALUES的占位符顺序完全对应,否则会出现字段值错位的问题。
方案2:修改SQL为命名占位符,直接使用字典
这种方式更直观,也不容易出错,尤其当字段较多时。把你的SQL语句里的?替换成对应字段名的命名占位符(前缀加:):
cur.execute("INSERT INTO COINS (Identifier, symbol, description) VALUES (:Identifier, :symbol, :description);", to_db)
这样直接传入字典to_db就可以了,SQLite会自动根据键名匹配对应的占位符。
完整示例(结合API数据获取)
给你一个从CoinDesk API获取数据并插入SQLite的完整示例,用方案2的方式:
import sqlite3 import requests # 1. 获取API数据 response = requests.get("https://api.coindesk.com/v1/bpi/currentprice.json") data = response.json() bpi_data = data["bpi"]["USD"] # 这里以USD数据为例,你可以根据需求调整 # 2. 准备插入的字典数据 to_db = { "Identifier": bpi_data["code"], "symbol": bpi_data["symbol"], "description": bpi_data["description"] } # 3. 连接SQLite并插入 conn = sqlite3.connect("coins.db") cur = conn.cursor() # 确保表存在(如果还没创建的话) cur.execute(""" CREATE TABLE IF NOT EXISTS COINS ( Identifier TEXT PRIMARY KEY, symbol TEXT, description TEXT ) """) # 使用命名占位符插入 cur.execute("INSERT INTO COINS (Identifier, symbol, description) VALUES (:Identifier, :symbol, :description);", to_db) conn.commit() conn.close()
这样就能完美解决你遇到的编程错误啦。
内容的提问来源于stack exchange,提问作者Niknak
相关产品推荐
相关产品推荐

