python + sqlalchemy : calling stored procedures in a loop

标签 python mysql sqlalchemy

我有一个 python 脚本,它定期查询 mysql 数据库中的数据(使用 sqlalchemy 0.7.4)。它通过运行存储过程来实现。如果过程返回任何内容,脚本将尝试处理数据(这部分与数据库无关),然后使用第二个过程将结果保存回来。

在此之后它会休眠一段时间(通常是一分钟)然后再次休眠直到停止。它应该能够运行数周。

我经常会遇到这个错误:“在回滚无效事务之前无法重新连接”。我已经使用我能找到的各种信息进行了一些更改,我想知道这是否是实现我想要的目标的好方法:

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:test@127.0.0.1/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)

我已经对此进行了测试,但我几乎只是编写它,所以我没有进行任何长期测试。我想先听听您的意见。

编辑: 本来我是用连接来执行查询的,像这样(省略了大部分和上面相同的脚本):

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

最佳答案

您正在使用 session 接口(interface),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

如果这会生成相同的异常,那么发布完整的堆栈跟踪会很有用。异常(exception)是 friend 而不是对手。 :)

关于 python + sqlalchemy : calling stored procedures in a loop,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14955382/

相关文章:

python - 将 where 与 pandas 和分类列一起使用时出错

php - Laravel Eloquent 关系——如何组合 id 和 date 上的两个关系?

php - 按最重复的值排序 mysql 列并在 php 中显示

mysql - group_concat Mysql 如何在一个查询中选择

python - SQLalchemy pickle 类型在数据库中存储超过需要

python - Gunicorn 服务环境文件格式?

python - WxPython[文本Ctrl] : The way of locate the cursor to end of text using TextCtrl function.

python - 如何使用 SqlAlchemy 按 id 查询数据库?

python - 输出子进程调用的命令行?

python - SQLAlchemy 和线程