У меня есть MySQL база данных, которая содержит несколько таблиц, имеющих структуру, подобную этой:
CREATE TABLE IF NOT EXISTS `table1` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`key1` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE (`key1`)
);
В моей программе Python, которая использует Twisted Framework, мне нужно выполнить ряд в основном идентичные операции с каждой из этих таблиц:
- Проверить, присутствует ли указанное значение в столбце
key
таблицы. - Если оно есть, вернуть соответствующее ему
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
Или я должен сделать что-то еще?