使用 Twisted 和 Oracle 从 dbpool.runQuery 而不是数据中获取延迟

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

我正在尝试使用 Twisted 和 runQuery 从 Oracle 获取一些数据,并不断获取 Deferred 而不是实际数据。 如何解决? 部分代码(我去掉了一些不必要的部分,但思路应该很清晰):

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',
    user=ORACLE_USER,
    password=ORACLE_PASSWORD,
    dsn=ORACLE_DSN, port='49161')

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

a = ask_db()
print(a)

如果这很重要,我在其他模块中得到了反应堆 运行。 提前谢谢你。

更新: 在@notorious.no 的帮助下得到了工作代码,返回数据而不是 Deferred with Python 3.5:

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

    return defer.returnValue(data) 

你得到一个 Deferred 是因为你正在调用一个 inlineCallback 而总是 return 一个 Deferred。您还误解了 yield 的作用。它实际上并不是 return 来自 inlinceCallback 的值,它只是在等待结果。使用 defer.returnValue() 到 return 一个值(如果您使用的是 Python 3.4+,则可以使用简单的 return)。您的代码应该如下所示:

from __future__ import print_function
#...

@defer.inlineCallbacks
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
reactor.run()

您之前的内容与此答案之间的区别在于添加了回调,因此当 runQuery() return 具有值时,将执行回调并且 ask_db() 实际上return这是您关心的值。

参考资料