使用来自Twite中的SQLite的id进行增量选择

时间:2012-06-13 19:04:03

标签: sqlite twisted

我试图在每次调用函数时一次从SQLite中的表中选择一行数据,并且我希望每次调用时该行都会递增(self.count在其他地方初始化并且' line& #39;这里无关紧要)我在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()

DB在另一个程序中创建,因此:

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,但没有区别,我仍然得到同样的错误。基本上,如果II在return语句中将uid设置为10或更多(注释掉返回)它可以工作,但是如果我在第一次返回时将uid设置为xuId(即uid =?,xuId),则仅当xuId低于10时才有效据我所知,API文档没有说明为什么会发生这种情况。(我还禁用了插入数据库以消除这种情况并检查了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.

感谢。

1 个答案:

答案 0 :(得分:0)

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

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

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