Python3 sqlalchemy pymysql gevent sqlalchemy.util.queue.Empty gevent.hub.LoopExit:此操作将永久阻止

时间:2015-09-25 16:06:58

标签: python-3.x sqlalchemy gevent pymysql

我在我的应用程序中一起使用python 3.4和sqlalchemy以及pymsql和gevent和芹菜。有时在sql数据库调用期间,会发生以下错误,不知道为什么会发生。有什么想法吗?

[2015-09-24 15:19:32,790: ERROR/Worker-1] Exception during reset or similar
Traceback (most recent call last):
  File "/usr/local/lib/python3.4/dist-packages/sqlalchemy/pool.py", line 950, in _do_get
    return self._pool.get(wait, self._timeout)
  File "/usr/local/lib/python3.4/dist-packages/sqlalchemy/util/queue.py", line 145, in get
    raise Empty
sqlalchemy.util.queue.Empty

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.4/dist-packages/sqlalchemy/pool.py", line 567, in _finalize_fairy
    fairy._reset(pool)
  File "/usr/local/lib/python3.4/dist-packages/sqlalchemy/pool.py", line 701, in _reset
    pool._dialect.do_rollback(self)
  File "/usr/local/lib/python3.4/dist-packages/sqlalchemy/dialects/mysql/base.py", line 2354, in do_rollback
    dbapi_connection.rollback()
  File "/usr/local/lib/python3.4/dist-packages/pymysql/connections.py", line 711, in rollback
    self._read_ok_packet()
  File "/usr/local/lib/python3.4/dist-packages/pymysql/connections.py", line 685, in _read_ok_packet
    pkt = self._read_packet()
  File "/usr/local/lib/python3.4/dist-packages/pymysql/connections.py", line 882, in _read_packet
    packet_header = self._read_bytes(4)
  File "/usr/local/lib/python3.4/dist-packages/pymysql/connections.py", line 899, in _read_bytes
    data = self._rfile.read(num_bytes)
  File "/usr/lib/python3.4/socket.py", line 371, in readinto
    return self._sock.recv_into(b)
  File "/usr/local/lib/python3.4/dist-packages/gevent/_socket3.py", line 282, in recv_into
    self._wait(self._read_event)
  File "/usr/local/lib/python3.4/dist-packages/gevent/_socket3.py", line 97, in _wait
    self.hub.wait(watcher)
  File "/usr/local/lib/python3.4/dist-packages/gevent/hub.py", line 360, in wait
    assert result is unique, 'Invalid switch into %s: %r (expected %r)' % (getcurrent(), result, unique)
AssertionError: Invalid switch into <greenlet.greenlet object at 0x7fb774422800>: <gevent.event.AsyncResult object at 0x7fb76d323198> (expected <object object at 0x7fb777ff82d0>)
[2015-09-24 15:19:32,911: ERROR/MainProcess] Task ppp.start_job[b574f2cd-4e9d-4f0f-97cc-79dd1ddee666] raised unexpected: LoopExit('This operation would block forever',)
Traceback (most recent call last):
  File "/usr/local/lib/python3.4/dist-packages/celery/app/trace.py", line 240, in trace_task
    R = retval = fun(*args, **kwargs)
  File "/usr/local/lib/python3.4/dist-packages/celery/app/trace.py", line 438, in __protected_call__
    return self.run(*args, **kwargs)
  File "/home/aaa/ppp/tasks/start_job.py", line 45, in start_job
    add_all_to_db(data_to_insert)
  File "/home/aaa/ppp/tasks/utils/sqldb.py", line 284, in add_all_to_db
    session.close()
  File "/home/aaa/ppp/tasks/utils/sqldb.py", line 270, in get_session
  File "/usr/local/lib/python3.4/dist-packages/sqlalchemy/sql/schema.py", line 3404, in create_all
    tables=tables)
  File "/usr/local/lib/python3.4/dist-packages/sqlalchemy/engine/base.py", line 1615, in _run_visitor
    with self._optional_conn_ctx_manager(connection) as conn:
  File "/usr/lib/python3.4/contextlib.py", line 59, in __enter__
    return next(self.gen)
  File "/usr/local/lib/python3.4/dist-packages/sqlalchemy/engine/base.py", line 1608, in _optional_conn_ctx_manager
    with self.contextual_connect() as conn:
  File "/usr/local/lib/python3.4/dist-packages/sqlalchemy/engine/base.py", line 1798, in contextual_connect
    self.pool.connect(),
  File "/usr/local/lib/python3.4/dist-packages/sqlalchemy/pool.py", line 338, in connect
    return _ConnectionFairy._checkout(self)
  File "/usr/local/lib/python3.4/dist-packages/sqlalchemy/pool.py", line 644, in _checkout
    fairy = _ConnectionRecord.checkout(pool)
  File "/usr/local/lib/python3.4/dist-packages/sqlalchemy/pool.py", line 440, in checkout
    rec = pool._do_get()
  File "/usr/local/lib/python3.4/dist-packages/sqlalchemy/pool.py", line 963, in _do_get
    return self._create_connection()
  File "/usr/local/lib/python3.4/dist-packages/sqlalchemy/pool.py", line 285, in _create_connection
    return _ConnectionRecord(self)
  File "/usr/local/lib/python3.4/dist-packages/sqlalchemy/pool.py", line 411, in __init__
    self.connection = self.__connect()
  File "/usr/local/lib/python3.4/dist-packages/sqlalchemy/pool.py", line 538, in __connect
    connection = self.__pool._creator()
  File "/usr/local/lib/python3.4/dist-packages/sqlalchemy/engine/strategies.py", line 90, in connect
    return dialect.connect(*cargs, **cparams)
  File "/usr/local/lib/python3.4/dist-packages/sqlalchemy/engine/default.py", line 377, in connect
    return self.dbapi.connect(*cargs, **cparams)
  File "/usr/local/lib/python3.4/dist-packages/pymysql/__init__.py", line 88, in Connect
    return Connection(*args, **kwargs)
  File "/usr/local/lib/python3.4/dist-packages/pymysql/connections.py", line 644, in __init__
    self._connect()
  File "/usr/local/lib/python3.4/dist-packages/pymysql/connections.py", line 823, in _connect
    (self.host, self.port), self.connect_timeout)
  File "/usr/local/lib/python3.4/dist-packages/gevent/socket.py", line 51, in create_connection
    for res in getaddrinfo(host, port, 0 if has_ipv6 else AF_INET, SOCK_STREAM):
  File "/usr/local/lib/python3.4/dist-packages/gevent/_socketcommon.py", line 193, in getaddrinfo
    return get_hub().resolver.getaddrinfo(host, port, family, socktype, proto, flags)
  File "/usr/local/lib/python3.4/dist-packages/gevent/resolver_thread.py", line 34, in getaddrinfo
    return self.pool.apply_e(self.expected_errors, _socket.getaddrinfo, args, kwargs)
  File "/usr/local/lib/python3.4/dist-packages/gevent/threadpool.py", line 222, in apply_e
    success, result = self.spawn(wrap_errors, expected_errors, function, args, kwargs).get()
  File "/usr/local/lib/python3.4/dist-packages/gevent/event.py", line 233, in get
    result = self.hub.switch()
  File "/usr/local/lib/python3.4/dist-packages/gevent/hub.py", line 349, in switch
    return greenlet.switch(self)
gevent.hub.LoopExit: This operation would block forever

我的get_session函数:

def get_session():
    engine = create_engine('mysql+pymysql://{0}:{1}@{2}/{3}'.format(SQL_USR, SQL_PASS, SQL_HOST, DB_NAME),
                           echo=True, pool_size=200, pool_recycle=360)
    Base.metadata.create_all(engine)
    Session = sessionmaker(bind=engine)
    session = Session()
    return session

2 个答案:

答案 0 :(得分:0)

本周,我遇到了一些类似于你的奇怪问题,python3.4sqlalchemyoracle。我发布了我发现的解决方案,以防它帮助你。

我有一些程序对python2.7运行完全正常,但我不时花费一些时间尝试将它们移植到3.4。有几个失败,其中一些失败与oracle通过sqlalchemy访问并遵循某种模式。失败的最简单方案是将数据加载到数据库中;基本上程序会永远失速。我没有像你这样的例外,但我猜这个问题的根源可能和你的一样。

我想在这里发布一个问题,但是我期待它只是我机器中的设置问题,无论如何我不知道如何以有意义的方式表达问题。我做了很多试验,得到了简单的方案正常工作

  • postgresql适用于2.7和3.4
  • 如上所述
  • oracle为2.7

这导致我进入更多的考验,最终我做了一个改变,有点盲目地说,我必须说,修正了它。我正在做这样的负担,

for user_id in users_set:
    reg = UserRank(user_id=int(user_id), rank_exec_id=rank_exec_id, rank_step_id=rank_step_id,
                   rank=rank_df.loc[user_id])
    session.add(reg)
session.commit()

其中rank_df.loc[user_id]的类型为numpy.float64,我将其更改为

for user_id in users_set:
    reg = UserRank(user_id=int(user_id), rank_exec_id=rank_exec_id, rank_step_id=rank_step_id,
                   rank=float(rank_df.loc[user_id]))
    session.add(reg)
session.commit()

因此将其转换为原始python float。它开始工作了,虽然我还没有真正理解这个问题。

为了完整起见,这是表的类,

class UserRank(Base):
    __tablename__ = 'user_rank'
    user_id = Column(BigInteger, primary_key=True)
    rank_exec_id = Column(String(256), primary_key=True)
    rank_step_id = Column(String(256), primary_key=True)
    rank = Column(Float)

老实说,我几乎不相信自己的解释,但我希望它能以某种方式帮助你。

答案 1 :(得分:0)

你使用gevent。你为它申请了猴子补丁吗?有关如何应用此修补程序,请参阅http://www.gevent.org/gevent.monkey.html