Я использую Python 3.6, mysql-connector-python 8.0.11 и 8.0.11
MySQL Community Server - GPL. В рассматриваемой таблице используется механизм innoDB.
При использовании MySQL Workbench я могу ввести:
ИСПОЛЬЗОВАНИЕ теста; НАЧАТЬ СДЕЛКУ; ВЫБРАТЬ * ИЗ ЗАДАЧ ГДЕ task_status! = 1 ПРЕДЕЛ 1 ДЛЯ ОБНОВЛЕНИЯ;
И это обеспечивает 1 запись, как ожидалось:
Когда я использую скрипт, использующий python3 (с той же машины - тот же доступ и т. Д.):
* SQL QRY: START TRANSACTION; SELECT * FROM test WHERE task_status != 1 LIMIT 1 FOR UPDATE;
* SQL RES: No result set to fetch from.
Это отладочный вывод из моего скрипта. Если я изменю запрос на обычный SELECT, я получу вывод.
* SQL QRY: SELECT * FROM test WHERE task_status != 1 LIMIT 1;
* SQL RES: [(1, 0, 'TASK0001')]
Я знаю, что SELECT * это не тот путь, а просто попытка получить какой-то ответ.
Я пытаюсь разрешить нескольким рабочим сценариям поднять задачу, при этом рабочие не выполняют одну и ту же задачу:
- Выполните операцию выбора и строки, чтобы заблокировать задачу, чтобы запрос «ВЫБРАТЬ» других рабочих их не отображал,
- Установить статус задачи на «обрабатывается» и разблокировать запись.
Это мое первое занятие по запиранию, так что это новая земля. Я могу делать обычные запросы, заполнять таблицы и т. Д., Так что имею некоторый опыт, но не с блокировкой.
ТАБЛИЦА создания:
create table test
(
id int auto_increment
primary key,
task_status int not null,
task_ref varchar(16) not null
);
Вопросы:
Это правильное мышление? То есть Есть ли более питонский / MySQL способ сделать это?
Есть ли какой-то особый способ, которым я должен инициировать соединение mysql? Почему это работает с использованием MySQL, а не с помощью сценария? Я пытался использовать прямой mysql, и это тоже работает - поэтому я думаю, что это разъем Python, который может потребоваться настроить правильно, поскольку это единственный компонент не работает.
В настоящее время я использую 'autocommit = 1' для разъема и 'buffered = True' для курсора. Я знаю, что вы можете установить 'autocommit = 0' в SQL до 'START TRANSACTION', так что понимайте, для блокировки мне может понадобиться это сделать, но для всех других транзакций я бы предпочел оставить автокоммит включенным. Это нормально и / или выполнимо?
КОД:
#!/usr/bin/env python
import mysql.connector
import pprint
conn = mysql.connector.connect(user='testuser',
password='testpass',
host='127.0.0.1',
database='test_db',
autocommit=True)
dbc = conn.cursor(buffered=True)
qry = "START TRANSACTION; SELECT * FROM 'test' WHERE task_status != 1 LIMIT 1 ON UPDATE;"
sql_select = dbc.execute(qry)
try:
output = dbc.fetchall()
except mysql.connector.Error as e:
print(" * SQL QRY: {0}".format(qry))
print(" * SQL RES: {0}".format(e))
exit()
else:
print(" * SQL QRY: {0}".format(qry))
print(" * SQL RES: {0}".format(output))
Большое спасибо,
Frank