SQLAlchemy select语句执行随机挂起

时间:2015-12-15 16:32:58

标签: python mysql sql sqlalchemy

以下代码:

from sqlalchemy import create_engine

class SqlLogger(object):
  def __init__(self,
               hostname = 'xxx',
               user = 'xxx',
               password = 'xxx',
               database='xxx'
               ):
    self.engine = create_engine(
      'mysql+mysqlconnector://{}:{}@{}/{}'.format(
          user,
          password,
          hostname,
          database),
      echo=False,
      pool_recycle=300) # re-connect after 5 minutes
    self.checkout(-1)


  def __del__(self):
    self.engine.dispose()


  def checkout(self,run_number):
    connection = self.engine.connect()
    print(1)
    statement = '''
      select * from INPUT_PARAMETERS
      where RUN_NUMBER = {}
      '''.format(run_number)
    print(2)
    result = connection.execute(statement)
    print(3)
    for row in result:
      print(row)
    print(4)
    connection.close()
    print(5)


sql = SqlLogger()

随机地无限期挂起(有时它会执行正常,有时它会挂起)。当它挂起时,它将打印1和2,即它挂起connection.execute(statement)。我连接的服务器是google cloud sql数据库。当我使用localhost时,我没有问题。

问题:问题可能是什么原因?我怎么能避免它?

调试信息:

这是我使用echo =“debug”时的输出。数字1和2来自脚本中的打印命令。

当它挂起时:

2015-12-15 15:36:43,997 INFO sqlalchemy.engine.base.Engine SHOW VARIABLES LIKE 'sql_mode'
2015-12-15 15:36:43,997 INFO sqlalchemy.engine.base.Engine {}
2015-12-15 15:36:44,070 DEBUG sqlalchemy.engine.base.Engine Col (u'Variable_name', u'Value')
2015-12-15 15:36:44,071 DEBUG sqlalchemy.engine.base.Engine Row (u'sql_mode', u'NO_ENGINE_SUBSTITUTION')
2015-12-15 15:36:44,249 INFO sqlalchemy.engine.base.Engine SELECT DATABASE()
2015-12-15 15:36:44,250 INFO sqlalchemy.engine.base.Engine {}
2015-12-15 15:36:44,322 DEBUG sqlalchemy.engine.base.Engine Col (u'DATABASE()',)
2015-12-15 15:36:44,322 DEBUG sqlalchemy.engine.base.Engine Row (u'SIMULATION_LOGS',)
2015-12-15 15:36:44,683 INFO sqlalchemy.engine.base.Engine SELECT CAST('test plain returns' AS CHAR(60)) AS anon_1
2015-12-15 15:36:44,683 INFO sqlalchemy.engine.base.Engine {}
2015-12-15 15:36:44,900 INFO sqlalchemy.engine.base.Engine SELECT CAST('test unicode returns' AS CHAR(60)) AS anon_1
2015-12-15 15:36:44,900 INFO sqlalchemy.engine.base.Engine {}
1
2
2015-12-15 15:36:45,407 INFO sqlalchemy.engine.base.Engine 
      select * from INPUT_PARAMETERS
      where RUN_NUMBER = -1

2015-12-15 15:36:45,407 INFO sqlalchemy.engine.base.Engine {}
2015-12-15 15:36:45,486 INFO sqlalchemy.engine.base.Engine ROLLBACK

当它没有挂起时:

2015-12-15 15:36:37,100 INFO sqlalchemy.engine.base.Engine SHOW VARIABLES LIKE 'sql_mode'
2015-12-15 15:36:37,100 INFO sqlalchemy.engine.base.Engine {}
2015-12-15 15:36:37,174 DEBUG sqlalchemy.engine.base.Engine Col (u'Variable_name', u'Value')
2015-12-15 15:36:37,175 DEBUG sqlalchemy.engine.base.Engine Row (u'sql_mode', u'NO_ENGINE_SUBSTITUTION')
2015-12-15 15:36:37,318 INFO sqlalchemy.engine.base.Engine SELECT DATABASE()
2015-12-15 15:36:37,318 INFO sqlalchemy.engine.base.Engine {}
2015-12-15 15:36:37,390 DEBUG sqlalchemy.engine.base.Engine Col (u'DATABASE()',)
2015-12-15 15:36:37,390 DEBUG sqlalchemy.engine.base.Engine Row (u'SIMULATION_LOGS',)
2015-12-15 15:36:37,779 INFO sqlalchemy.engine.base.Engine SELECT CAST('test plain returns' AS CHAR(60)) AS anon_1
2015-12-15 15:36:37,779 INFO sqlalchemy.engine.base.Engine {}
2015-12-15 15:36:37,994 INFO sqlalchemy.engine.base.Engine SELECT CAST('test unicode returns' AS CHAR(60)) AS anon_1
2015-12-15 15:36:37,994 INFO sqlalchemy.engine.base.Engine {}
1
2
2015-12-15 15:36:38,520 INFO sqlalchemy.engine.base.Engine 
      select * from INPUT_PARAMETERS
      where RUN_NUMBER = -1

2015-12-15 15:36:38,520 INFO sqlalchemy.engine.base.Engine {}
2015-12-15 15:36:38,603 DEBUG sqlalchemy.engine.base.Engine Col (u'RUN_NUMBER', ...)
3
4
5

当我在查询之前插入connection.begin()时(即在print(1)命令之前),我得到一个实际的错误消息而不是冻结。这是echoed语句之后的调试输出,之前的所有内容都与上面相同:

2015-12-15 18:47:04,044 INFO sqlalchemy.engine.base.Engine 
      select * from INPUT_PARAMETERS
      where RUN_NUMBER = 1

2015-12-15 18:47:04,044 INFO sqlalchemy.engine.base.Engine {}
Traceback (most recent call last):
  File "sql_connection.py", line 44, in <module>
    sql = SqlLogger()
  File "sql_connection.py", line 19, in __init__
    self.checkout(1)
  File "sql_connection.py", line 35, in checkout
    result = connection.execute(statement)
  File "/usr/lib64/python2.7/site-packages/sqlalchemy/engine/base.py", line 906, in execute
    return self._execute_text(object, multiparams, params)
  File "/usr/lib64/python2.7/site-packages/sqlalchemy/engine/base.py", line 1054, in _execute_text
    statement, parameters
  File "/usr/lib64/python2.7/site-packages/sqlalchemy/engine/base.py", line 1146, in _execute_context
    context)
  File "/usr/lib64/python2.7/site-packages/sqlalchemy/engine/base.py", line 1344, in _handle_dbapi_exception
    util.reraise(*exc_info)
  File "/usr/lib64/python2.7/site-packages/sqlalchemy/engine/base.py", line 1139, in _execute_context
    context)
  File "/usr/lib64/python2.7/site-packages/sqlalchemy/engine/default.py", line 450, in do_execute
    cursor.execute(statement, parameters)
  File "/usr/lib64/python2.7/site-packages/mysql/connector/cursor.py", line 514, in execute
    self._handle_result(self._connection.cmd_query(stmt))
  File "/usr/lib64/python2.7/site-packages/mysql/connector/connection.py", line 488, in cmd_query
    result = self._handle_result(self._send_cmd(ServerCmd.QUERY, query))
  File "/usr/lib64/python2.7/site-packages/mysql/connector/connection.py", line 409, in _handle_result
    columns[i] = self._protocol.parse_column(self._socket.recv())
  File "/usr/lib64/python2.7/site-packages/mysql/connector/protocol.py", line 234, in parse_column
    (packet, _) = utils.read_lc_string(packet)  # table
  File "/usr/lib64/python2.7/site-packages/mysql/connector/utils.py", line 199, in read_lc_string
    if buf[0] == 251:  # \xfb
IndexError: bytearray index out of range

2 个答案:

答案 0 :(得分:0)

这是一种解决方法,然后是解决方案。似乎问题只存在于使用mysql-connector时。将engine = create_engine('mysql+mysqlconnector://...')替换为engine = create_engine('mysql+mysqldb://...')时,我不会遇到上述错误。

答案 1 :(得分:0)

使用mysql.connector.__version__ == 2.0.3时遇到了同样的问题。 升级到2.1.3版是一种解决方案。

您可以在网站上找到最新版本的mysq.connector: mysql connector