微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

python – 在Web应用程序中使用Postgres:“事务中止”错误

最近我出于性能原因将我正在从MySQL开发的Web应用程序移动到Postgresql(我需要PostGIS提供的功能).现在经常遇到以下错误

当前事务被中止,命令被忽略直到事务块结束

服务器应用程序使用mod_python.在hailing函数中发生错误(即为该特定客户端创建新会话的函数).这里是适当的代码段(异常发生在调用sessionAppId的行上:

def hello(req):
req.content_type = "text/json"
req.headers_out.add('Cache-Control', "no-store, no-cache, must-revalidate")
req.headers_out.add('Pragma', "no-cache")
req.headers_out.add('Expires', "-1")
instance = req.hostname.split(".")[0]

cookieSecret = '....' # whatever :-)
receivedCookies = Cookie.get_cookies(req, Cookie.SignedCookie, secret = cookieSecret)
sessionList = receivedCookies.get('sessions', None)
sessionId = str(uuid.uuid4())
if sessionList:
    if type(sessionList) is not Cookie.SignedCookie:
        return "{status: 'error', errno:1, errmsg:'Permission denied.'}"
    else:
        sessionList = sessionList.value.split(",")
        for x in sessionList[:]:
            revisionCookie = receivedCookies.get('rev_' + str(sessionAppId(x, instance)), None)
            # more processing here....
# .....
cursors[instance].execute("lock revision, app, timeout IN SHARE MODE")
cursors[instance].execute("insert into app (type, active, active_revision, contents, z) values ('session', true, %s, %s, 0) returning id", (cRevision, sessionId))
sAppId = cursors[instance].fetchone()[0]
cursors[instance].execute("insert into revision (app_id, type) values (%s, 'active')", (sAppId,))
cursors[instance].execute("insert into timeout (app_id, last_seen) values (%s, Now())", (sAppId,))
connections[instance].commit()
# .....

这里是sessionAppId本身:

def sessionAppId(sessionId, instance):
cursors[instance].execute("select id from app where type='session' and contents = %s", (sessionId, ))
row = cursors[instance].fetchone()
if row == None:
    return 0
else:
    return row[0]

一些澄清和其他问题:

> cursors [instance]和connections [instance]是数据库连接以及在此域名上提供的Web应用程序实例的游标.即同一台服务器提供example1.com和example2.com,并根据请求所针对的服务器名称使用这些词典调用相应的数据库.
>我真的需要锁定hello()函数中的表吗?
>每个浏览器选项卡维护一个单独的会话需要hello()中的大多数代码.我找不到与cookie有关的方法,因为打开网站的浏览器标签共享cookie池.有没有更好的方法呢?

非常感谢你.

解决方法:

错误是由于先例错误引起的.看看这段代码

>>> import psycopg2
>>> conn = psycopg2.connect('')
>>> cur = conn.cursor()
>>> cur.execute('select current _date')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
psycopg2.ProgrammingError: Syntax error at or near "_date"
LINE 1: select current _date
                       ^

>>> cur.execute('select current_date')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
psycopg2.InternalError: current transaction is aborted, commands ignored until end of transaction block

>>> conn.rollback()
>>> cur.execute('select current_date')
>>> cur.fetchall()
[(datetime.date(2010, 2, 5),)]
>>> 

如果您熟悉twisted,请查看twisted.enterprise.adbapi以获取如何处理游标的示例.基本上你应该总是提交或回滚你的游标:

try:
    cur.execute("...")
    cur.fetchall()
    cur.close()
    connection.commit()
except:
    connection.rollback()

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐