0

我试图从 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.

谢谢。

4

1 回答 1

0

考虑runQuery 的 API 文档。接下来,考虑这三个函数调用之间的区别:

c = a, b
f(a, b)
f((a, b))
f(c)

最后,不要解释错误消息。总是逐字引用它们。尽可能复制/粘贴;当您手动转录它们时记下它们。

于 2012-06-14T14:04:07.903 回答