[Twisted] adpapi - Query 실행하기/ CallBack 함수에 argument 전달하기

일단, Query를 실행하는 방법은 크게 두 가지를 쓸 수 있겠다.

runQuery()를 사용하는 방법과, runInteraction()을 사용하는 방법이다.

주어진 table에서 10개의 row를 가져오고자 한다고 했을때,

1) runQuery() 사용하기

def getCount():
return dbpool.runQuery("select * from test")

def printResult(l):
if l:
result = l[0][0]
print l[0][0], " records"
else:

print "no rows fetched"

dbpool = adbapi.ConnectionPool('MySQLdb', db='abcd', user='abcd', passwd='abcd')
getCount().addCallback(printResult)
reactor.run()


2) runInteraction() 사용하기

def get10():
return dbpool.runInteraction(_get10)

def _get10(txn):
txn.execute("select * from test")
result = txn.fetchall()

if result:
return result

else:
return None

def print10(data):
if data != None:
print data, ' data found'

else:
print 'no data'

 

dbpool = adbapi.ConnectionPool('MySQLdb', db='abcd', user='abcd', passwd='abcd')
getCount().addCallback(printResult)


get10().addCallback(print10)
reactor.run()


위와 같은 서로 다른 방법으로 구성할 수 있다. 이때, runInteraction을 사용하면, function에 대해 실행할 수 있고, transaction 단위로 실행시킬 수 있다는 점이다. 

또한, 별도의 메타정보가 함께 결과에 포함되지 않는 것 같으므로, 메타 정보를 query를 실행할 때 미리 주고 싶다면??
 
이렇게 하는 수도 있겠다. 실행이 synchronous 하지 않으므로, 어떤 필드가 어떻게 매핑되어야 할지는 query와 함께 움직여야 하지 않을까? 그래서, Callback 함수에 테이블의 메타 정보를 한번 심어봤다. runQuery()와, runInteraction()에 각각. 동작이 하는 경우는 runInteraction()의 경우이다.

예를 들어, 넘기고자 하는 파라미터가 list l = ('a','b','c','d')라고 하면, 각각의 함수는 다음과 같이 바뀔 것이다.

1. runQuery()의 경우

def getCount(param-list):
return dbpool.runQuery("select * from test", param_list)

def printResult(l, param_list):
# 동일

그러나, 이 경우는 에러가 발생한다. runQuery의 파라미터로 쿼리문과 함께 사용자 정의 파라미터를 전달하고 싶지만, printResult callback 문으로 전달될 수 없다. (물론 방법이 있겠지만, 나는 모르겠다. 아직은 ^^;)

한편, 이 상황을 runInteraction()을 사용하는 경우에는 해결 가능한 문제가 된다.

2. runInteraction()의 경우

def get10(param_list):
return dbpool.runInteraction(_get10, param_list)   # _get10 파라미터로 param_list 지정

def _get10(txn, param_list):
# param_list로 하고 싶은 작업을 할 수 있다
txn.execute("select * from test")
result = txn.fetchall()
if result:
return [param_list, result]
else:
return [param_list, None]
# 결과를 list로 return 한다.

def print10(data):
if data != None:
meta = data[0]      # param_list from _get10
record = data[1]    # result from _get10

get10()이나 _get10()에 다른 형태로 param_lsit를 곧바로 넘기려고 하면, tuple에 addCallback할
수 없다는 에러가 뜨거나, 원하는 형태로 전달할 수 없음을 확인했다.

따라서, 위의 방법과 같이, result와 넘겨주려는 데이터를 함께 리스트로 넘겨서 직접 확인하는
방법을 구상해보았다. (리스트 또는 dict 형태로 하면 좋을 것 같다.) 더 좋은 방법이 떠오르면,
추가로 기록해야겠다.






 


 

댓글

Designed by JB FACTORY