函数从Twisted中的MySQL数据库返回值

问题描述 投票:0回答:1

我有一个MySQL数据库,其中包含多个具有如下结构的表:

CREATE TABLE IF NOT EXISTS `table1` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `key1` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE (`key1`)
);

在我使用Twisted框架的Python程序中,我需要执行一系列这些表中的每一个的操作几乎相同:

  1. 检查表的key列中是否存在给定值。
  2. 如果是,则返回其对应的id
  3. 如果不是,则将该值插入表中并返回其对应的id

由于操作本质上是相同的,因此这很有意义由具有表和键名的函数执行的操作,以及该值作为参数并返回ID。

我该怎么做?我做不到

import MySQLdb

from twisted.python import log
from twisted.enterprise.adbapi import ConnectionPool
from twisted.internet.defer import inlineCallbacks

class ReconnectingConnectionPool(ConnectionPool):
    def _runInteraction(self, interaction, *args, **kw):
        try:
            return ConnectionPool._runInteraction(
                self, interaction, *args, **kw)
        except MySQLdb.OperationalError as e:   # pylint: disable=no-member
            if e[0] not in (2003, 2006, 2013):
                raise e
            conn = self.connections.get(self.threadID())
            self.disconnect(conn)
            # Try the interaction again
            return ConnectionPool._runInteraction(
                self, interaction, *args, **kw)

dbh = ReconnectingConnectionPool(
    'MySQLdb',
    db='database',
    user='user',
    passwd='password'
)

@inlineCallbacks
def get_id(table, column, entry):
    try:
        r = yield dbh.runQuery("SELECT `id` FROM `{}` WHERE `{}` = '{}'".format(table, column, entry))
        if r:
            id = r[0][0]
        else:
            yield dbh.runQuery("INSERT INTO `{}` (`{}`) VALUES ('{}')".format(table, column, entry))
            r = yield dbh.runQuery('SELECT LAST_INSERT_ID()')
            id = int(r[0][0])
    except Exception as e:
        log.msg(e)
        id = 0
    return id

因为函数get_id是一个生成器,并且它们不能直接返回值。

我应该使用defer.returnValue(id)代替return id吗?还是我应该使用dbh.runQuery('query').addCallback(get_result)其中get_result是这样的函数

def get_result(value):
    return value

还是我应该做其他事情?

python mysql database twisted
1个回答
0
投票

get_id函数本身将返回deferred,因为您使用inlineCallbacks包装它。

然后您使用以下命令调用函数:

get_id().addCallback(your_callback_to_retrive_the_id)

get_id函数中,如果您使用的是python3,则可以使用returndefer.returnValue语句返回结果。

在python2中,您只能使用defer.returnValue

from __future__ import print_function

from twisted.internet import reactor
from twisted.internet.defer import Deferred, returnValue, inlineCallbacks



def runQuery(query):
    # suppose this will fetch the result from database
    d = Deferred()

    # simulate the delay waiting for the database to give the results
    # using reactor.callLater
    reactor.callLater(0.3, d.callback, 1); # 1 here is the (result)
    return d


@inlineCallbacks
def get_id(table, column, entry):
    r = yield runQuery("foobar")
    # r is the result from the database
    #if python3
    return r # or returnValue(r)

    # if python2
    # returnValue(r)


# every time you call a function that is wrapped with inlineCallbacks
# the return value of that function is Deferred

d = get_id('messages', 'message', 'Foo')
d.addCallback(lambda r: print("Result: %r" % (r, )))

reactor.run()
© www.soinside.com 2019 - 2024. All rights reserved.