我正在使用Python脚本对我们的外发邮件进行某些流控制,主要是检查用户是否在发送垃圾邮件。
该脚本通过SQLObject
与数据库建立持久连接。在某些情况下,连接被第三方丢弃(例如我们的防火墙由于空闲过多而关闭连接),SQLObject
没有注意到它已经关闭并且它继续发送查询死TCP处理程序,导致这样的日志条目:
Feb 06 06:56:07 mailsrv2 flow: ERROR Processing request error: [Failure instance: Traceback: <class 'psycopg2.InterfaceError'>: connection already closed#012/usr/lib/python2.7/threading.py:524:__bootstrap#012/usr/lib/python2.7/threading.py:551:__bootstrap_inner#012/usr/lib/python2.7/threading.py:504:run#012--- <exception caught here>---#012
/opt/scripts/virtualenv/local/lib/python2.7/site-packages/twisted/python/threadpool.py:191:_worker#012
/opt/scripts/virtualenv/local/lib/python2.7/site-packages/twisted/python/context.py:118:callWithContext#012
/opt/scripts/virtualenv/local/lib/python2.7/site-packages/twisted/python/context.py:81:callWithContext#012
/opt/scripts/flow/server.py:91:check#012
/opt/scripts/flow/flow.py:252:check#012
/opt/scripts/flow/flow.py:155:append_to_log#012
/opt/scripts/virtualenv/local/lib/python2.7/site-packages/SQLObject-1.3.1-py2.7.egg/sqlobject/main.py:1226:__init__#012
/opt/scripts/virtualenv/local/lib/python2.7/site-packages/SQLObject-1.3.1-py2.7.egg/sqlobject/main.py:1274:_create#012
/opt/scripts/virtualenv/local/lib/python2.7/site-packages/SQLObject-1.3.1-py2.7.egg/sqlobject/main.py:1298:_SO_finishCreate#012
/opt/scripts/virtualenv/local/lib/python2.7/site-packages/SQLObject-1.3.1-py2.7.egg/sqlobject/dbconnection.py:468:queryInsertID#012
/opt/scripts/virtualenv/local/lib/python2.7/site-packages/SQLObject-1.3.1-py2.7.egg/sqlobject/dbconnection.py:327:_runWithConnection#012
/opt/scripts/virtualenv/local/lib/python2.7/site-packages/SQLObject-1.3.1-py2.7.egg/sqlobject/postgres/pgconnection.py:191:_queryInsertID#012]
这让我觉得确实必须对这种情况进行一些回调,否则就不会写入日志条目。我使用该回调建立与数据库的新连接。我一直无法找到任何的相关文档。
有没有人知道它是否可以实现该回调以及如何声明它?
感谢。
答案 0 :(得分:3)
我们是SQLAlchemy
而非SQLObject
的常规用户。根据2010年的这个帖子(http://sourceforge.net/p/sqlobject/mailman/message/26460439),SQLObject不支持PostgreSQL的重新连接逻辑。这是一个旧线程,但似乎没有任何关于在SQLObject中解决这个问题的讨论。
我有三个建议的解决方案。
第一个解决方案是探索连接池。当SQLObject检测到psycopg2已断开连接时,它可能提供一种打开新连接对象的方法。我无法保证会这样做,但如果确实如此,那么这个解决方案将是您最好的,因为它需要您进行最少量的更改。
第二个解决方案是将后端从Postgres切换到MySQL。 SQLObject文档提供了有关如何使用mysql驱动程序的重新连接逻辑的信息 - http://sourceforge.net/p/mysql-python/feature-requests/9
第三种解决方案是切换到SQLAlchemy作为您的ORM并使用他们的连接池版本。根据核心事件文档,如果在删除或关闭连接时使用池,则会打开一个新连接 - http://docs.sqlalchemy.org/en/rel_0_9/core/exceptions.html#sqlalchemy.exc.DisconnectionError
祝你好运