2016-04-07 2 views
0

У меня есть база данных MySql (работает с использованием запасом Docker изображения) и содержит таблицу, определенную так:Python MySql запросы молча неудачу

CREATE TABLE `Edits` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `context` varchar(255) NOT NULL, 
    `field` varchar(255) NOT NULL, 
    `value` text, 
    `username` varchar(255) DEFAULT NULL, 
    `requested` datetime DEFAULT NULL, 
    PRIMARY KEY (`id`,`context`,`field`) 
) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=latin1 

Я подключение к нему в приложении WSGI, и мой код подключения выглядит следующим образом:

import contextlib 
import MySQLdb 

mysql = MySQLdb.connect(host = 'host', db = 'db') 

def _cursor(): 
    mysql.ping(True) 
    return contextlib.closing(mysql.cursor()) 

def _exec(sql, params = None): 
    with _cursor() as c: 
    c.execute(sql, params) 

def save_edits(id, context, field, value, username): 
    return _exec('REPLACE INTO Edits SET id = %(id)s, context = %(context)s, 
    field = %(field)s, value = %(value)s, username = %(username)s, 
    requested = UTC_TIMESTAMP()', { 
     'id': id, 
     'context': context, 
     'field': field, 
     'value': value, 
     'username': username, 
    }) 

Когда я вызываю функцию save_edits, он не бросает исключение, но он не может обновить базу данных. Кроме того, попытка выполнить запрос REPLACE INTO Edits SET id = 1, context = 'x', field = 'y', value = 'z', username = 'foo', requested = UTC_TIMESTAMP(); через оболочку mysql впоследствии завершилась с ошибкой ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction. Однако, если я жду около 5 минут, эта ошибка уходит, и я снова могу запустить запрос REPLACE INTO к базе данных MySql.

Что происходит? Как я могу исправить эту ошибку?

+1

Вам нужно явно зафиксировать обновление? – snakecharmerb

+0

Первое, что я попробую, это запустить запрос 'SET SQL_SAFE_UPDATE = 0;' иногда безопасные обновления поймают вещи и не позволят вам обновить – Joris

ответ

0

Оказывается, что autocommit по умолчанию является false, и закрытие курсора без закрытия соединения сохраняет транзакцию открытой. Я изменил метод на:

def _exec(sql, params = None): 
    with _cursor() as c: 
    c.execute(sql, params) 
    mysql.commit() 

И это исправило проблему.

Смежные вопросы