Alex Ivanov Alex Ivanov - 2 months ago 16
Python Question

Get Deferred from dbpool.runQuery instead of data with Twisted and Oracle

I am trying to get some data from Oracle, using Twisted and runQuery and keep getting Deferred instead of actual data.
How can this be solved?
Some code (I excluded some unnecessary parts, but the idea should be clear):

from twisted.enterprise import adbapi
from twisted.internet import defer
import service_config

ORACLE_DSN = service_config.oracle_dsn
ORACLE_USER = service_config.oracle_user
ORACLE_PASSWORD = service_config.oracle_password
dbpool = adbapi.ConnectionPool('cx_Oracle',
dsn=ORACLE_DSN, port='49161')

def ask_db():
data = yield dbpool.runQuery("SELECT * FROM customer")

a = ask_db()

I got reactor running in other module, if that is important.
Thank you in advance.

With help of got working code, returning data instead of Deferred with Python 3.5:

def ask_db(request):
data = yield dbpool.runQuery(request)

return defer.returnValue(data)


You get a Deferred because you're calling an inlineCallback which always returns a Deferred. You're also misinterpreting what yield does. It doesn't actually return a value from an inlinceCallback it just wait's for a result. Use defer.returnValue() to return a value (you can use a simple return if you're using Python 3.4+). This is what your code should look like:

from __future__ import print_function

def ask_db():
    data = yield dbpool.runQuery("SELECT * FROM customer")
    defer.returnValue(data)    # actually return a value

a = ask_db()    # this returns a Deferred so add callbacks!
a.addCallback(print)    # add a useful callback to processes query list

The difference between what you had previously and this answer is that a callback is added so when the runQuery() returns with a value, the callback is executed and ask_db() actually returns a value you care about.