我正在研究一种名为Skybot的模块化机器人的IRC机器人。
默认情况下,还有另外两个模块使用sqlite3数据库;他们都被删除了,他们的桌子掉了下来,所以我知道问题出在我正在做的事情上。
我只在整个事情中调用3 db.execute()
个语句,并且它们都立即被提交。这个问题也没有受到查询的影响,但锁仍然存在。
相关代码:
def db_init(db):
db.execute("create table if not exists searches"
"(search_string UNIQUE PRIMARY KEY,link)")
db.commit()
return db
def get_link(db, inp):
row = db.execute("select link from searches where"
" search_string=lower(?) limit 1",
(inp.lower(),)).fetchone()
db.commit()
return row
def store_link(db, stub, search):
db.execute("insert into searches (search_string, link) VALUES (?, ?)", (search.lower(), stub))
db.commit()
return stub
如果脚本只需要触摸db_init()
和get_link()
就可以轻松通过,但如果需要在数据库解锁时调用store_link()
,则会执行插入,但不会似乎是以未来调用get_link()
可以读取它直到机器人重新启动的方式提交它。
机器人的db.py:
import os
import sqlite3
def get_db_connection(conn, name=''):
"returns an sqlite3 connection to a persistent database"
if not name:
name = '%s.%s.db' % (conn.nick, conn.server)
filename = os.path.join(bot.persist_dir, name)
return sqlite3.connect(filename, isolation_level=None)
bot.get_db_connection = get_db_connection
我自己调整了isolation_level
,原来是timeout=10
。我很难过。
编辑:get_db_connection()
:
main.py(主循环):
def run(func, input):
args = func._args
if 'inp' not in input:
input.inp = input.paraml
if args:
if 'db' in args and 'db' not in input:
input.db = get_db_connection(input.conn)
if 'input' in args:
input.input = input
if 0 in args:
out = func(input.inp, **input)
else:
kw = dict((key, input[key]) for key in args if key in input)
out = func(input.inp, **kw)
else:
out = func(input.inp)
if out is not None:
input.reply(unicode(out))
...
def start(self):
uses_db = 'db' in self.func._args
db_conns = {}
while True:
input = self.input_queue.get()
if input == StopIteration:
break
if uses_db:
db = db_conns.get(input.conn)
if db is None:
db = bot.get_db_connection(input.conn)
db_conns[input.conn] = db
input.db = db
try:
run(self.func, input)
except:
traceback.print_exc()
答案 0 :(得分:0)
如上所述,在您的函数中发送conn以及db。如果您自己编写代码,那么您将知道数据库的实际位置。通常你会做类似的事情:
db = sqlite3.connect('database.db')
conn = db.cursor()
然后用于一般用法:
db.execute("...")
conn.commit()
因此,在您的情况下:
def db_init(conn,db):
db.execute("create table if not exists searches"
"(search_string UNIQUE PRIMARY KEY,link)")
conn.commit()
return db
def get_link(conn,db, inp):
row = db.execute("select link from searches where"
" search_string=lower(?) limit 1",
(inp.lower(),)).fetchone()
conn.commit()
return row
def store_link(conn,db, stub, search):
db.execute("insert into searches (search_string, link) VALUES (?, ?)", (search.lower(), stub))
conn.commit()
return stub
答案 1 :(得分:0)
基于您已将isolation_level设置为自动更新:
sqlite3.connect(filename, isolation_level=None)
您的代码中的commit
语句不需要任何内容
编辑:
在execute
语句中包含您的try
语句,以便您至少有机会了解正在发生的事情,例如
import sqlite3
def get_db(name=""):
if not name:
name = "db1.db"
return sqlite3.connect(name, isolation_level=None)
connection = get_db()
cur = connection.cursor()
try:
cur.execute("create table if not exists searches"
"(search_string UNIQUE PRIMARY KEY,link)")
except sqlite3.Error as e:
print 'Searches create Error '+str(e)
try:
cur.execute("insert into searches (search_string, link) VALUES (?, ?)", ("my search", "other"))
except sqlite3.Error as e:
print 'Searches insert Error '+str(e)
cur.execute("select link from searches where search_string=? limit 1", ["my search"])
s_data = cur.fetchone()
print 'Result:', s_data