2013-02-19 4 views
1

У меня есть скрипт python, который периодически запрашивает базу данных mysql для данных (используя sqlalchemy 0.7.4). Это делается путем запуска хранимой процедуры. Если процедура вернет что-либо, скрипт попытается обработать данные (эта часть не имеет ничего общего с БД), а затем сохранит результаты с помощью второй процедуры.python + sqlalchemy: вызов хранимых процедур в цикле

После этого он будет спать в течение определенного времени (обычно на минуту) и до него все до остановки. Он должен работать неделями.

Я часто получаю эту ошибку: «Не удается повторно подключиться, пока недействительная транзакция не вернется». Я сделал некоторые изменения, используя все виды информации, которые смогли найти об этом, и мне интересно, если это хороший способ достижения того, что я хочу:

from sqlalchemy import create_engine, exc 
from sqlalchemy.orm import sessionmaker 
from sqlalchemy import text, func 
import time 

class StoredProcedures(): 
    _engine = None 
    _connection = None 
    _session = None 

    def __init__(self, cs): 
     self._engine = create_engine(cs, encoding='utf-8', echo=False, pool_recycle=600) 
     self._connection = self._engine.connect() 
     Session = sessionmaker(bind=self._engine) 
     self._session = Session() 

    def sp_test_1(self, user_id): 
     t = self._session.begin(subtransactions=True) 

     try: 
      query = 'call sp_get_files(%d)'%user_id 
      result = self._session.execute(query).fetchall() 
      t.close() 
      return result 
     except exc.DBAPIError, e: #Proper way of reconnecting? 
      t.rollback() 
      time.sleep(5) 
      self._connection = self._engine.connect() 
      Session = sessionmaker(bind=self._engine) 
      self._session = Session() 
     except: 
      t.rollback() 

     return None 


cs = "mysql://test:[email protected]/test_db" 
db_stored_procedures = StoredProcedures(cs) 

while (True): 
    files = db_stored_procedures.sp_test_1(1) 
    if len(files) > 0: 
     print "This is where processing happens" 
     #And this is where the second procedure would be called to store the results 
    time.sleep(15) 

Я испытал это, но я довольно много раз писал поэтому я не проводил долговременного тестирования. Сначала я бы хотел, чтобы вы высказали свое мнение.

EDIT: Первоначально я использовал соединение, чтобы выполнить запрос, например, так (опущена большая часть сценария, который был таким же, как один из приведенных выше):

def sp_test_1(self, user_id): 
    t = self._connection.begin() 

    try: 
     query = 'call sp_get_files(%d)'%user_id 
     result = self._connection.execute(query).fetchall() 
     t.close() 
     return result 
    except exc.DBAPIError, e: 
     #same as above 
    except: 
     t.rollback() 

    return None 

ответ

0

Вы используете Session интерфейс, which uses a Transaction object internally, поэтому я не думаю, что вам нужно сделать свое собственное управление транзакциями.

Я не вижу особой нужды что-либо за пределами простой:

def sp_test_1(self, user_id): 

    query = 'call sp_get_files(%d)'%user_id 
    result = self._session.execute(query).fetchall() 
    return result 

Если порождает такое же исключение, было бы полезно, если вы разместите полный трассировки стека. Исключения являются друзьями, а не противниками. :)

+0

Я попытаюсь дать вам трассировку стека, но это происходит спорадически, и я не всегда могу его воспроизвести. У меня также есть другая проблема с хранимыми процедурами, но я думаю, что это лучше подходит для нового вопроса. – gkres

+0

Если это спорадическое, я бы долго смотрел на журнал MySQL. – JosefAssad

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