我试图从 SQLite 中的表中为每次调用该函数一次仅选择一行数据,并且我希望该行在每次调用时递增(self.count 在其他地方初始化,'line' 在这里无关紧要)我我在 Twisted 中使用 adbapi 连接池连接到数据库。这是我尝试过的代码:
def queryBTData4(self,line):
self.count=self.count+1
uuId=self.count
query="SELECT co2_data, patient_Id FROM btdata4 WHERE uid=:uid",{"uid": uuId}
d = self.dbpool.runQuery(query)
return d
如果我只是在数据库中设置 uid=1 或任何其他数字(我在创建数据库时使用了 uid 的自动增量),则此代码有效,但是当我尝试为 uid 分配一个值(即通过 uuId 的 self.count)时,它报告说运算符必须是字符串或 unicode。(我都尝试过,但似乎没有帮助)但是,我知道当我使用游标和执行命令时,上面的查询语句在以前的程序中工作得很好,但我不能看看为什么它在这里不起作用。我尝试了各种组合并搜索了解决方案,但还没有找到任何可行的方法。(我也尝试过带括号和其他形式的语句)
感谢您的任何帮助或建议。
这是整个代码:
from twisted.internet import protocol, reactor
from twisted.protocols import basic
from twisted.enterprise import adbapi
import sqlite3, time
class ServerProtocol(basic.LineReceiver):
def __init__(self):
self.conn = sqlite3.connect('biomed2.db',check_same_thread=False)
self.dbpool = adbapi.ConnectionPool("sqlite3" , 'biomed2.db', check_same_thread=False)
def connectionMade(self):
self.sendLine("conn made")
factory = protocol.ClientFactory()
factory.protocol = ClientProtocol
factory.originator = self
reactor.connectTCP('localhost', 1234, factory)
def lineReceived(self, line):
self._received = line
self.insertBTData4(self._received)
self.sendLine("line recvd")
def forwardLine(self, recipient):
recipient.sendLine(self._received)
def insertBTData4(self,data):
print "data in insert is",data
chx=data
PID=2
device_ID=5
query="INSERT INTO btdata4(co2_data,patient_Id, sensor_Id) VALUES ('%s','%s','%s')" % (chx, PID, device_ID)
dF = self.dbpool.runQuery(query)
return dF
class ClientProtocol(basic.LineReceiver):
def __init__(self):
self.conn = sqlite3.connect('biomed2.db',check_same_thread=False)
self.dbpool = adbapi.ConnectionPool("sqlite3" , 'biomed2.db', check_same_thread=False)
self.count=0
def connectionMade(self):
print "server-client made connection with client"
self.factory.originator.forwardLine(self)
#self.transport.loseConnection()
def lineReceived(self, line):
d=self.queryBTData4(self)
d.addCallbacks(self.sendData,self.printError )
def queryBTData4(self,line):
self.count=self.count+1
query=("SELECT co2_data, patient_Id FROM btdata4 WHERE uid=:uid",{"uid": uuId})
dF = self.dbpool.runQuery(query)
return dF
def sendData(self,line):
data=str(line)
self.sendLine(data)
def printError(self,error):
print "Got Error: %r" % error
error.printTraceback()
def main():
factory = protocol.ServerFactory()
factory.protocol = ServerProtocol
reactor.listenTCP(4321, factory)
reactor.run()
if __name__ == '__main__':
main()
数据库是在另一个程序中创建的,因此:
import sqlite3, time, string
conn = sqlite3.connect('biomed2.db')
c = conn.cursor()
c.execute('''CREATE TABLE btdata4
(uid INTEGER PRIMARY KEY, co2_data integer, patient_Id integer, sensor_Id integer)''')
主程序将数据放入服务器套接字并插入数据库。在客户端套接字端,一次一行地从数据库中删除数据并发送到外部服务器。如果需要,该程序还可以将数据从服务器端发送到客户端,但我目前不这样做。
在 queryBTData() 中,每次调用该函数时,计数都会增加,然后我将该值分配给 uuId,然后将其传递给查询。我有这个查询语句在我不使用 adbapi 的程序中工作,但它似乎在这里不起作用。我希望这足够清楚,但如果没有,请告诉我,我会再试一次。
编辑:
我已修改程序以一次从数据库中获取一行(请参阅下面的 queryBTData()),但遇到了另一个问题。
def queryBTData4(self,line):
self.count=self.count+1
xuId= self.count
#xuId=10
return self.dbpool.runQuery("SELECT co2_data FROM btdata4 WHERE uid = ?",xuId)
#return self.dbpool.runQuery("SELECT co2_data FROM btdata4 WHERE uid = 10")
当计数达到 10 时,我收到一个错误(我将在下面发布),指出:“提供的绑定数量不正确。当前语句使用 1,提供了 2 个”
我尝试将 xuId 设置为 10(请参阅注释掉的 xuId=10 行),但我仍然遇到相同的错误。但是,如果我切换返回语句(以注释掉返回),我确实得到了正确的行而没有错误。我已经尝试将 xuId 转换为 unicode 但这没有区别,我仍然得到同样的错误。基本上,如果我在 return 语句中将 uid 设置为 10 或更多(注释掉 return)它可以工作,但如果我在第一次返回时将 uid 设置为 xuId(即 uid=?,xuId),它仅在 xuId 低于 10 时才有效. 据我所知,API 文档没有给出为什么会发生这种情况的任何线索。(我还禁用了插入 DB 以消除这种情况并检查了 SQLite3_ 限制,即 999)
这是我在使用第一个 return 语句时遇到的错误。
Got Error: <twisted.python.failure.Failure <class 'sqlite3.ProgrammingError'>>
Traceback (most recent call last):
File "c:\python26\lib\threading.py", line 504, in __bootstrap
self.__bootstrap_inner()
File "c:\python26\lib\threading.py", line 532, in __bootstrap_inner
self.run()
File "c:\python26\lib\threading.py", line 484, in run
self.__target(*self.__args, **self.__kwargs)
--- <exception caught here> ---
File "c:\python26\lib\site-packages\twisted\python\threadpool.py", line 207, i
n _worker
result = context.call(ctx, function, *args, **kwargs)
File "c:\python26\lib\site-packages\twisted\python\context.py", line 118, in c
allWithContext
return self.currentContext().callWithContext(ctx, func, *args, **kw)
File "c:\python26\lib\site-packages\twisted\python\context.py", line 81, in ca
llWithContext
return func(*args,**kw)
File "c:\python26\lib\site-packages\twisted\enterprise\adbapi.py", line 448, i
n _runInteraction
result = interaction(trans, *args, **kw)
File "c:\python26\lib\site-packages\twisted\enterprise\adbapi.py", line 462, i
n _runQuery
trans.execute(*args, **kw)
sqlite3.ProgrammingError: Incorrect number of bindings supplied. The current sta
tement uses 1, and there are 2 supplied.
谢谢。