У меня есть скрипт 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
Я попытаюсь дать вам трассировку стека, но это происходит спорадически, и я не всегда могу его воспроизвести. У меня также есть другая проблема с хранимыми процедурами, но я думаю, что это лучше подходит для нового вопроса. – gkres
Если это спорадическое, я бы долго смотрел на журнал MySQL. – JosefAssad