Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Orm SQLAlchemy+;PyMysql:如何从陈旧的连接错误中恢复(PyMysql.err.InternalError)_Orm_Sqlalchemy_Pymysql - Fatal编程技术网

Orm SQLAlchemy+;PyMysql:如何从陈旧的连接错误中恢复(PyMysql.err.InternalError)

Orm SQLAlchemy+;PyMysql:如何从陈旧的连接错误中恢复(PyMysql.err.InternalError),orm,sqlalchemy,pymysql,Orm,Sqlalchemy,Pymysql,很明显,我似乎遗漏了一些东西:我希望SQLAlchemy通过在“签出”时重新创建旧连接来从旧连接中恢复 我的应用程序使用SQLAlchemy ORM(严格来说是ORM,根本不使用表达式语言)连接并与MYSQL数据库通信。当一段时间内没有活动时,池中的连接似乎过时并生成 sqlalchemy.exc.InternalError: (pymysql.err.InternalError) (1046, 'No database selected') 我尝试过设置预ping,也在create_引擎中

很明显,我似乎遗漏了一些东西:我希望SQLAlchemy通过在“签出”时重新创建旧连接来从旧连接中恢复

我的应用程序使用SQLAlchemy ORM(严格来说是ORM,根本不使用表达式语言)连接并与MYSQL数据库通信。当一段时间内没有活动时,池中的连接似乎过时并生成

sqlalchemy.exc.InternalError: (pymysql.err.InternalError) (1046, 'No database selected') 
我尝试过设置预ping,也在create_引擎中设置了pool_recycle

我创建了一个示例来测试这一点:请注意,pool_recycle非常积极,可以更快地尝试产生错误情况(在我的应用程序中,它是3600)

#我的测试程序在.py文件中
#-完全工作的代码-但在create_引擎中替换name/pwd/Dbserver
从sqlalchemy.ext.declarative导入声明性基础
从sqlalchemy.orm导入sessionmaker
从sqlalchemy导入创建引擎、事件、exc
从sqlalchemy导入元数据、列、整数、日期时间
从日期时间导入日期时间
从时间上导入睡眠
导入pymysql
引擎=创建引擎('mysql+pymysql://name:pwd@127.0.0.1',
池\u pre\u ping=True,池\u recycle=1)
会话=会话生成器(绑定=引擎)
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
execute('DROP DATABASE IF EXISTS satest')
#创建并使用数据库
execute('CREATE DATABASE IF NOT exist satest')
engine.execute('USE satest')
#准备创建表
元数据=元数据(引擎)
#session=scoped_session(sessionmaker(bind=engine))
base=声明性_base()
TblFoo类(基本类):
__tablename_uuu='Foo'
id=列(整数,主键=True,可空=False)
计数器=列(整数)
dateTime=列(dateTime)
def createFooRecords():
计数=1
当计数小于1000000时:
realCount=count
尝试:
全球会议
会话=会话()
rec=TblFoo(计数器=计数,
dateTime=dateTime.today().isoformat())
会话.添加(rec)
session.commit()
计数+=1
最后:
session.close()
如果realCount!=计数:
睡眠(realCount*5)
@事件。侦听(引擎,“处理错误”)
def接收处理错误(异常上下文):
打印('句柄错误:',异常\u上下文)
如果isinstance(异常\u上下文.original\u异常,
pymysql.err.InternalError):
如果str(异常上下文原始异常)='1046':
打印('内部错误:')
其他:
print('某些其他错误:',
异常(上下文。原始异常)
@事件。侦听(引擎“失效”)
def接收失效(dbapi连接、连接记录、异常):
打印('DBAPI连接:',DBAPI_连接)
打印('连接记录:',连接记录)
打印('异常:',异常)
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
base.metadata.create_all(引擎)
createFooRecords()
当然,engine.pool中的连接在1秒后超时,第二次调用session.add(rec)失败

“handle_error”确实会被调用

Handle Error:  <sqlalchemy.engine.base.ExceptionContextImpl object at 0x1093311d0>
Some other error:  (1046, 'No database selected')
Traceback (most recent call last):
.... stacktrace omitted for brevity, finally .... 
ssqlalchemy.exc.InternalError: (pymysql.err.InternalError) (1046, 'No database selected') [SQL: 'INSERT INTO `Foo` (counter, `dateTime`) VALUES (%(counter)s, %(dateTime)s)'] [parameters: {'counter': 2, 'dateTime': '2019-08-28T15:07:45.184456'}] (Background on this error at: http://sqlalche.me/e/2j85)
处理错误:
其他一些错误:(1046,“未选择数据库”)
回溯(最近一次呼叫最后一次):
.... 为了简洁起见,最后省略了stacktrace。。。。
ssqlachemy.exc.InternalError:(pymysql.err.InternalError)(1046,'未选择数据库')[SQL:'插入'Foo'(计数器,`dateTime`)值(%%(计数器)s,%%(dateTime)s)][参数:{'counter':2,'dateTime':'2019-08-28815:07:45.184456'(此错误的背景信息位于:http://sqlalche.me/e/2j85)
“无效”永远不会被调用

那么,SQLAlchemy为什么不重新创建连接,因为它很清楚它会在1秒内过期(pool_recycle value)。(不清楚它是否正在进行预ping-如何验证?--但如果发生,它仍然没有重新创建连接。)

诚然,错误来自PyMysql,但设置在SQLAlchemy中

当然,我希望这是可恢复的,所以我在try-catch中添加了一个except:但也许重新创建引擎不是正确的方法

def createFooRecords():
    count = 1
    while count < 1000000:
        realCount = count
        try:
            global Session
            session = Session()
            rec = TblFoo(counter=count, 
                         dateTime=datetime.today().isoformat())
            session.add(rec)
            session.commit()
            count += 1
        except exc.InternalError as e:
            print('{} Exception: {}'.format(count, e))
            global engine
            engine.dispose()
            engine = create_engine('mysql+pymysql://name:pwd@127.0.0.1',
                                   pool_pre_ping=True, pool_recycle=1)
            Session = sessionmaker(bind=engine)
            continue
        except Exception as e2:
            print('Error', e2)
            raise
        finally:
            session.close()

        if realCount != count:
            sleep(realCount*5)



Handle Error:  <sqlalchemy.engine.base.ExceptionContextImpl object at 0x1076b6fd0>
Some other error:  (1046, 'No database selected')
2 Exception: (pymysql.err.InternalError) (1046, 'No database selected') [SQL: 'INSERT INTO `Foo` (counter, `dateTime`) VALUES (%(counter)s, %(dateTime)s)'] [parameters: {'counter': 2, 'dateTime': '2019-08-28T15:09:47.498157'}] (Background on this error at: http://sqlalche.me/e/2j85)
2 Exception: (pymysql.err.InternalError) (1046, 'No database selected') [SQL: 'INSERT INTO `Foo` (counter, `dateTime`) VALUES (%(counter)s, %(dateTime)s)'] [parameters: {'counter': 2, 'dateTime': '2019-08-28T15:09:47.503714'}] (Background on this error at: http://sqlalche.me/e/2j85)
def createFooRecords():
计数=1
当计数小于1000000时:
realCount=count
尝试:
全球会议
会话=会话()
rec=TblFoo(计数器=计数,
dateTime=dateTime.today().isoformat())
会话.添加(rec)
session.commit()
计数+=1
除exc.InternalError为e外:
打印(“{}异常:{}”。格式(计数,e))
全球引擎
处理引擎
引擎=创建引擎('mysql+pymysql://name:pwd@127.0.0.1',
池\u pre\u ping=True,池\u recycle=1)
会话=会话生成器(绑定=引擎)
持续
例外情况除外,如e2:
打印('错误',e2)
提升
最后:
session.close()
如果realCount!=计数:
睡眠(realCount*5)
处理错误:
其他一些错误:(1046,“未选择数据库”)
2异常:(pymysql.err.InternalError)(1046,“未选择数据库”)[SQL:“插入到`Foo`(计数器,`dateTime`)值(%(计数器)s,%%(dateTime)s)][参数:{'counter':2,'dateTime':'2019-08-28815:09:47.498157'”(此错误的背景信息位于:http://sqlalche.me/e/2j85)
2异常:(pymysql.err.InternalError)(1046,“未选择数据库”)[SQL:“插入到`Foo`(计数器,`dateTime`)值(%(计数器)s,%%(dateTime)s)][参数:{'counter':2,'dateTime':'2019-08-28815:09:47.503714'”(此错误的背景信息位于:http://sqlalche.me/e/2j85)
。。。当“count”永远不递增时,会有无数的数据流

net,如何从陈旧的连接中恢复(最好是在签出时)。我有一个相当复杂的应用程序,它只使用ORM,并且有许多数据库(阅读:
def createFooRecords():
    count = 1
    while count < 1000000:
        realCount = count
        try:
            global Session
            session = Session()
            rec = TblFoo(counter=count, 
                         dateTime=datetime.today().isoformat())
            session.add(rec)
            session.commit()
            count += 1
        except exc.InternalError as e:
            print('{} Exception: {}'.format(count, e))
            global engine
            engine.dispose()
            engine = create_engine('mysql+pymysql://name:pwd@127.0.0.1',
                                   pool_pre_ping=True, pool_recycle=1)
            Session = sessionmaker(bind=engine)
            continue
        except Exception as e2:
            print('Error', e2)
            raise
        finally:
            session.close()

        if realCount != count:
            sleep(realCount*5)



Handle Error:  <sqlalchemy.engine.base.ExceptionContextImpl object at 0x1076b6fd0>
Some other error:  (1046, 'No database selected')
2 Exception: (pymysql.err.InternalError) (1046, 'No database selected') [SQL: 'INSERT INTO `Foo` (counter, `dateTime`) VALUES (%(counter)s, %(dateTime)s)'] [parameters: {'counter': 2, 'dateTime': '2019-08-28T15:09:47.498157'}] (Background on this error at: http://sqlalche.me/e/2j85)
2 Exception: (pymysql.err.InternalError) (1046, 'No database selected') [SQL: 'INSERT INTO `Foo` (counter, `dateTime`) VALUES (%(counter)s, %(dateTime)s)'] [parameters: {'counter': 2, 'dateTime': '2019-08-28T15:09:47.503714'}] (Background on this error at: http://sqlalche.me/e/2j85)