2013-11-12 4 views
0

Я пытаюсь запустить некоторые запросы, которые должны создавать временные таблицы, а затем возвращает набор результатов, но я не могу сделать это с MySQLdb api.Python MySQLdb не дождался результата

Я уже копаю что-то об этой проблеме, например here но без успеха.

Мой запрос выглядит так:

create temporary table tmp1 
select * from table1; 

alter tmp1 add index(somefield); 

create temporary table tmp2 
select * from table2; 

select * from tmp1 inner join tmp2 using(somefield); 

Это возвращает немедленно пустой результирующий набор. Если я перейду к клиенту mysql и сделаю show full processlist, я смогу увидеть мои запросы. Им требуется несколько минут. Почему курсор возвращается немедленно и не дожидается запроса для запуска.

Если я пытаюсь запустить другой запрос у меня есть «Команда из синхронизации, вы не можете запустить эту команду сейчас»

я уже пытался поставить свою связь с AUTOCOMMIT к Истинному

db = MySQLdb.connect(host='ip', 
       user='root', 
       passwd='pass', 
       db='mydb', 
       use_unicode=True 
    ) 
db.autocommit(True) 

Или положите каждый оператор в свой собственный cursor.execute() и между ними db.commit(), но без успеха тоже.

Помогите мне понять, в чем проблема? Я знаю, что mysql не поддерживает транзакции для некоторых операций, таких как alter table, но почему api не ждет, пока все закончится так же, как с select?

Кстати, я пытаюсь сделать это на ноутбуке ipython.

+0

Конец должен выполняться с помощью dbhandle, а не курсора .. db.commit() в коде выше. Это то, что вы пробовали? – erobbins

+0

Да, это опечатка. Когда я делаю 'db.commit()', я получаю ошибку синхронизации. – balsagoth

ответ

2

Я подозреваю, что вы передаете строку с несколькими операторами SQL непосредственно в функцию cursor.execute. Дело в том, что каждое из утверждений представляет собой запрос в своем собственном праве, поэтому неясно, что должен содержать набор результатов.

Вот пример, чтобы показать, что я имею в виду. Первый случай - передать набор чисел с запятой в execute, что, как я полагаю, имеется в настоящее время.

def query_single_sql(cursor): 
    print 'query_single_sql' 
    sql = [] 
    sql.append("""CREATE TEMPORARY TABLE tmp1 (id int)""") 
    sql.append("""INSERT INTO tmp1 VALUES (1)""") 
    sql.append("""SELECT * from tmp1""") 

    cursor.execute(';'.join(sql)) 
    print list(cursor.fetchall()) 

Выход:

query_single_sql 
[] 

Вы можете увидеть, что ничего не возвращается, даже несмотря на то, очевидно, данные в таблице и SELECT, используется.

Второй случай, когда каждый оператор выполняется как независимый запрос, а результаты печатаются для каждого запроса.

def query_separate_sql(cursor): 
    print 'query_separate_sql' 
    sql = [] 
    sql.append("""CREATE TEMPORARY TABLE tmp3 (id int)""") 
    sql.append("""INSERT INTO tmp3 VALUES (1)""") 
    sql.append("""SELECT * from tmp3""") 
    for query in sql: 
     cursor.execute(query) 
     print list(cursor.fetchall()) 

Выход:

query_separate_sql 
[] 
[] 
[(1L,)] 

Как вы можете видеть, мы потребляли результаты курсора для каждого запроса и окончательный запрос имеет результаты, которые мы ожидаем.

Я подозреваю, что даже если вы выдали несколько запросов, API имеет только обработчик первого запроса, и он немедленно возвращается, когда CREATE TABLE завершен. Я бы предложил сериализацию ваших запросов, как описано во втором примере выше.

+0

Да, вы правы. Моменты перед отправкой правильного ответа я смог выполнить все запросы отдельно. Как-то, когда я пробовал это раньше, у меня были ошибки, возможно, из-за использования старого соединения. Я очистил все (даже соединения mysql), и мне даже не нужно делать коммиты между ними. – balsagoth

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