Python sqlite3插入去重报错绑定数异常及URL冒号转义问题
问题解决方案
报错原因解析
- 第一个
sqlite3.ProgrammingError错误:你编写的INSERT语句里有2个?参数占位符,但你传入的value序列中每个元素只包含1个URL值,参数数量不匹配。 - 第二个
TypeError错误:executemany方法仅接受2个位置参数(SQL语句、参数序列),你修改传参逻辑时额外多传了位置参数,导致触发参数数量错误。
正确实现方案
写法1:兼容现有SQL逻辑的修复
你需要保证传入的参数序列中,每个子项包含两个相同的URL,匹配两个占位符的要求:
# 单条URL插入(用execute即可,不需要executemany) url = "待插入的链接" cur.execute( "INSERT INTO Link_Date (link) SELECT ? WHERE NOT EXISTS (SELECT * FROM Link_Date WHERE link = ?)", (url, url) ) conn.commit() # 批量URL插入(用executemany) url_list = ["链接1", "链接2", "链接3"] param_list = [(url, url) for url in url_list] cur.executemany( "INSERT INTO Link_Date (link) SELECT ? WHERE NOT EXISTS (SELECT * FROM Link_Date WHERE link = ?)", param_list ) conn.commit()
写法2:更推荐的简化方案
给link字段加唯一约束,直接用SQLite原生的INSERT OR IGNORE语法自动跳过重复值,不需要写复杂的判断逻辑,代码更简洁性能也更高:
-- 先给link字段加唯一索引(新建表时也可以直接在字段定义中加UNIQUE约束) CREATE UNIQUE INDEX IF NOT EXISTS idx_link_unique ON Link_Date(link);
后续插入代码可以简化为:
# 单条插入 cur.execute("INSERT OR IGNORE INTO Link_Date (link) VALUES (?)", (url,)) # 批量插入 cur.executemany("INSERT OR IGNORE INTO Link_Date (link) VALUES (?)", [(url,) for url in url_list]) conn.commit()
URL冒号转义问题
使用参数化查询(也就是上述的?占位符传参写法)时,不需要手动对URL中的冒号做任何转义,SQLite驱动会自动处理所有特殊字符,不会触发语法错误,也不存在SQL注入风险。不要手动拼接SQL字符串传入URL,即可避免所有特殊字符的解析问题。
内容的提问来源于stack exchange,提问作者Dobob
相关产品推荐
相关产品推荐

