SQLite 的绑定错误数量不正确
Incorrect Number of Bindings Error with SQLite
一些背景知识我在 python 2.7 中这样做是为了通过 SeoLib 获得 Alexa 排名,但如果这有助于解决这个问题或可能解决未来的问题,我完全愿意更新。
现在这个程序对我在预先确定的 csv 中拥有的网站进行排序,如下所示:
site
00rbt.com
我特别收到以下错误:
File "igorPanda.py", line 84, in <module>
update_site(site,cur_ip,cur_rank,cur_hash)
File "igorPanda.py", line 30, in update_site
(site))
sqlite3.ProgrammingError: Incorrect number of bindings supplied. The current statement uses 1, and there are 9 supplied.
发生此错误的位置是:
def update_site(site,cur_ip,cur_rank,cur_hash):
conn = sqlite3.connect('/root/Database/Sites.db')
cursor = conn.cursor()
with conn:
cursor.execute("SELECT EXISTS(SELECT * from sites WHERE site = ?)",
(site))
record = cursor.fetchone()
if record[0] == 1:
cursor.execute("UPDATE sites SET cur_ip = ?, cur_rank = ?, cur_hash = ? WHERE site = ?",
(cur_ip,cur_rank,cur_hash,site))
else:
cursor.execute("INSERT into sites values (?,?,?,?,?,?,?,?)",
(site,cur_ip,None,cur_rank,None,None,cur_hash,None))
除了导入之外,我的整个代码是:
#Updates the DB
def update_site(site,cur_ip,cur_rank,cur_hash):
conn = sqlite3.connect('/root/Database/Sites.db')
cursor = conn.cursor()
with conn:
cursor.execute("SELECT EXISTS(SELECT * from sites WHERE site = ?)",
(site))
record = cursor.fetchone()
if record[0] == 1:
cursor.execute("UPDATE sites SET cur_ip = ?, cur_rank = ?, cur_hash = ? WHERE site = ?",
(cur_ip,cur_rank,cur_hash,site))
else:
cursor.execute("INSERT into sites values (?,?,?,?,?,?,?,?)",
(site,cur_ip,None,cur_rank,None,None,cur_hash,None))
#Moves CSV for Historical Savings
bashmove = "mv top.csv /root/Desktop/scripts/results-igor/top-$(date +%m-%d-%Y).csv"
#Sets file with all sites to variable
filename='/root/Desktop/scripts/sorted.csv'
#Creates hash algorithm for later use
hasher = hashlib.sha256()
sess = requests.Session()
x = datetime.datetime.now()
date = x.strftime('%Y-%m-%d')
regex = r"^(?:https?:)?(?:\/\/)?(?:[^@\n]+@)?(?!www\.)?([^:\/\n]+)\w*\.\b(com|org|co|be|de|br|(\w+\b))" #regex to get stripepd website no https://www. or anything afte$
df = pd.DataFrame()
df = df.append(pd.read_csv(filename), ignore_index=True)
ip = "NOT FOUND"
for i in df.index:
#print(i)
site = df['site'][i]
try :
ip = socket.gethostbyname(site)
page = requests.get('http://' + df['site'][i], timeout=5)
hasher.update((page.text).encode('utf-8'))
except: #ignore errors if the site is bad
pass
try :
alexa_rank = seo.get_alexa('http://{}'.format(site)) #seolib gets the alexa ranking
#alexa_rank = None
except:
pass
site = site
cur_ip = ip
cur_rank = alexa_rank
cur_hash = hasher.hexdigest()
update_site(site,cur_ip,cur_rank,cur_hash)
rd = call(["/root/Desktop/scripts/./rDNSlookup.sh", site, ip]) #call bash script to get reverse DNS of ip
wi = call(["/root/Desktop/scripts/./whois.sh", site]) #call bash script to print host info
with open('/root/Desktop/scripts/IGOR_His/'+ date + 'sites.csv', 'a') as f:
print >> f, 'site: ',site,', ip: ',ip,', rank: ',alexa_rank, ', hash', cur_hash
shutil.copy("/root/Database/Sites.db", "/var/www/html/sites/Sites.db")
table有以下列:
site,cur_ip,prev_ip,cur_rank,prev_rank,play,cur_hash,prev_hash
TL;DR: 使用 (site,)
详细:
cursor.execute
期望第二个参数是可迭代的。
当您的代码显示:
cursor.execute("SELECT EXISTS(SELECT * from sites WHERE site = ?)", (site))
那么 (site)
不是元组 - 您可能打算通过将其包装在 ()
.
中将其转换为元组
所以你 meant/want 是:
cursor.execute("SELECT EXISTS(SELECT * from sites WHERE site = ?)", (site,))
注意额外的 ,
!
为避免这种元组混淆,您还可以使用列表:
cursor.execute("SELECT EXISTS(SELECT * from sites WHERE site = ?)", [site])
问题更详细:
cursor.execute("SELECT EXISTS(SELECT * from sites WHERE site = ?)", (site))
等同于:
cursor.execute("SELECT EXISTS(SELECT * from sites WHERE site = ?)", site)
与(在您的情况下)相同:
cursor.execute("SELECT EXISTS(SELECT * from sites WHERE site = ?)", "00rbt.com")
字符串 00rbt.com
被用作可迭代对象,由于它有 9 个字符,您会得到错误:
sqlite3.ProgrammingError: Incorrect number of bindings supplied. The current statement uses 1, and there are 9 supplied.
你得到这个错误,因为这里:
cursor.execute("SELECT EXISTS(SELECT * from sites WHERE site = ?)", (site))
你应该传递,作为 execute()
的第二个参数网络,一个元组而不仅仅是一个字符串。
这很容易通过添加这样的逗号来解决:
cursor.execute("SELECT EXISTS(SELECT * from sites WHERE site = ?)", (site,))
但是,如果您的 SQLite 版本是 3.24.0+,您应该考虑采取不同的方法,选择 UPSERT
作为执行您想要的操作的方法。
如果 site
值在 table 中不存在,您想要插入一个新行,或者如果它存在,则更新现有行。
因此,假设列 site
已经有一个唯一约束,您可以使用以下方法更有效地做到这一点:
sql = """
INSERT into sites values (?,?,?,?,?,?,?,?)
ON CONFLICT(site) DO UPDATE SET
cur_ip = EXCLUDED.cur_ip, cur_rank = EXCLUDED.cur_rank, cur_hash = EXCLUDED.cur_hash
"""
cursor.execute(sql, (site,cur_ip,None,cur_rank,None,None,cur_hash,None))
一些背景知识我在 python 2.7 中这样做是为了通过 SeoLib 获得 Alexa 排名,但如果这有助于解决这个问题或可能解决未来的问题,我完全愿意更新。
现在这个程序对我在预先确定的 csv 中拥有的网站进行排序,如下所示:
site
00rbt.com
我特别收到以下错误:
File "igorPanda.py", line 84, in <module>
update_site(site,cur_ip,cur_rank,cur_hash)
File "igorPanda.py", line 30, in update_site
(site))
sqlite3.ProgrammingError: Incorrect number of bindings supplied. The current statement uses 1, and there are 9 supplied.
发生此错误的位置是:
def update_site(site,cur_ip,cur_rank,cur_hash):
conn = sqlite3.connect('/root/Database/Sites.db')
cursor = conn.cursor()
with conn:
cursor.execute("SELECT EXISTS(SELECT * from sites WHERE site = ?)",
(site))
record = cursor.fetchone()
if record[0] == 1:
cursor.execute("UPDATE sites SET cur_ip = ?, cur_rank = ?, cur_hash = ? WHERE site = ?",
(cur_ip,cur_rank,cur_hash,site))
else:
cursor.execute("INSERT into sites values (?,?,?,?,?,?,?,?)",
(site,cur_ip,None,cur_rank,None,None,cur_hash,None))
除了导入之外,我的整个代码是:
#Updates the DB
def update_site(site,cur_ip,cur_rank,cur_hash):
conn = sqlite3.connect('/root/Database/Sites.db')
cursor = conn.cursor()
with conn:
cursor.execute("SELECT EXISTS(SELECT * from sites WHERE site = ?)",
(site))
record = cursor.fetchone()
if record[0] == 1:
cursor.execute("UPDATE sites SET cur_ip = ?, cur_rank = ?, cur_hash = ? WHERE site = ?",
(cur_ip,cur_rank,cur_hash,site))
else:
cursor.execute("INSERT into sites values (?,?,?,?,?,?,?,?)",
(site,cur_ip,None,cur_rank,None,None,cur_hash,None))
#Moves CSV for Historical Savings
bashmove = "mv top.csv /root/Desktop/scripts/results-igor/top-$(date +%m-%d-%Y).csv"
#Sets file with all sites to variable
filename='/root/Desktop/scripts/sorted.csv'
#Creates hash algorithm for later use
hasher = hashlib.sha256()
sess = requests.Session()
x = datetime.datetime.now()
date = x.strftime('%Y-%m-%d')
regex = r"^(?:https?:)?(?:\/\/)?(?:[^@\n]+@)?(?!www\.)?([^:\/\n]+)\w*\.\b(com|org|co|be|de|br|(\w+\b))" #regex to get stripepd website no https://www. or anything afte$
df = pd.DataFrame()
df = df.append(pd.read_csv(filename), ignore_index=True)
ip = "NOT FOUND"
for i in df.index:
#print(i)
site = df['site'][i]
try :
ip = socket.gethostbyname(site)
page = requests.get('http://' + df['site'][i], timeout=5)
hasher.update((page.text).encode('utf-8'))
except: #ignore errors if the site is bad
pass
try :
alexa_rank = seo.get_alexa('http://{}'.format(site)) #seolib gets the alexa ranking
#alexa_rank = None
except:
pass
site = site
cur_ip = ip
cur_rank = alexa_rank
cur_hash = hasher.hexdigest()
update_site(site,cur_ip,cur_rank,cur_hash)
rd = call(["/root/Desktop/scripts/./rDNSlookup.sh", site, ip]) #call bash script to get reverse DNS of ip
wi = call(["/root/Desktop/scripts/./whois.sh", site]) #call bash script to print host info
with open('/root/Desktop/scripts/IGOR_His/'+ date + 'sites.csv', 'a') as f:
print >> f, 'site: ',site,', ip: ',ip,', rank: ',alexa_rank, ', hash', cur_hash
shutil.copy("/root/Database/Sites.db", "/var/www/html/sites/Sites.db")
table有以下列:
site,cur_ip,prev_ip,cur_rank,prev_rank,play,cur_hash,prev_hash
TL;DR: 使用 (site,)
详细:
cursor.execute
期望第二个参数是可迭代的。
当您的代码显示:
cursor.execute("SELECT EXISTS(SELECT * from sites WHERE site = ?)", (site))
那么 (site)
不是元组 - 您可能打算通过将其包装在 ()
.
所以你 meant/want 是:
cursor.execute("SELECT EXISTS(SELECT * from sites WHERE site = ?)", (site,))
注意额外的 ,
!
为避免这种元组混淆,您还可以使用列表:
cursor.execute("SELECT EXISTS(SELECT * from sites WHERE site = ?)", [site])
问题更详细:
cursor.execute("SELECT EXISTS(SELECT * from sites WHERE site = ?)", (site))
等同于:
cursor.execute("SELECT EXISTS(SELECT * from sites WHERE site = ?)", site)
与(在您的情况下)相同:
cursor.execute("SELECT EXISTS(SELECT * from sites WHERE site = ?)", "00rbt.com")
字符串 00rbt.com
被用作可迭代对象,由于它有 9 个字符,您会得到错误:
sqlite3.ProgrammingError: Incorrect number of bindings supplied. The current statement uses 1, and there are 9 supplied.
你得到这个错误,因为这里:
cursor.execute("SELECT EXISTS(SELECT * from sites WHERE site = ?)", (site))
你应该传递,作为 execute()
的第二个参数网络,一个元组而不仅仅是一个字符串。
这很容易通过添加这样的逗号来解决:
cursor.execute("SELECT EXISTS(SELECT * from sites WHERE site = ?)", (site,))
但是,如果您的 SQLite 版本是 3.24.0+,您应该考虑采取不同的方法,选择 UPSERT
作为执行您想要的操作的方法。
如果 site
值在 table 中不存在,您想要插入一个新行,或者如果它存在,则更新现有行。
因此,假设列 site
已经有一个唯一约束,您可以使用以下方法更有效地做到这一点:
sql = """
INSERT into sites values (?,?,?,?,?,?,?,?)
ON CONFLICT(site) DO UPDATE SET
cur_ip = EXCLUDED.cur_ip, cur_rank = EXCLUDED.cur_rank, cur_hash = EXCLUDED.cur_hash
"""
cursor.execute(sql, (site,cur_ip,None,cur_rank,None,None,cur_hash,None))