gpt4 book ai didi

python-2.7 - SQLAlchemy 事务中的错误不会返回正确的回溯(Python 2.7)

转载 作者:行者123 更新时间:2023-12-04 12:48:07 31 4
gpt4 key购买 nike

在我当前的模型用户中,我有一个不能为空的字段“名称”。

我尝试创建一个用户对象,并将其添加到 Pyramid 提供的 DBSession 中,然后将其与事务一起提交,就像这样。

with transaction.manager:
u = models.User()
models.DBSession.add(u)

对于那些不使用 Pyramid 的人来说,DBSession 是:
DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension()))

现在,在我上面的交易中,我确实有一个验证问题 - 我需要为用户分配一个名称,但我没有。但是,我没有收到错误消息告诉我“您需要为您的用户分配一个名称!”,而是得到了这个:
<ipython-input-5-47d9c0e393f7> in <module>()
2 u = models.User()
----> 3 models.DBSession.add(u)
4

/home/user/Projects/env/local/lib/python2.7/site-packages/transaction-1.4.1-py2.7.egg/transaction/_manager.pyc in __exit__(self, t, v, tb)
118 def __exit__(self, t, v, tb):
119 if v is None:
--> 120 self.commit()
121 else:
122 self.abort()

/home/user/Projects/env/local/lib/python2.7/site-packages/transaction-1.4.1-py2.7.egg/transaction/_manager.pyc in commit(self)
109 """ See ITransactionManager.
110 """
--> 111 return self.get().commit()
112
113 def abort(self):

/home/user/Projects/env/local/lib/python2.7/site-packages/transaction-1.4.1-py2.7.egg/transaction/_transaction.py in commit(self)
276 tb = None
277 try:
--> 278 t, v, tb = self._saveAndGetCommitishError()
279 self._callAfterCommitHooks(status=False)
280 reraise(t, v, tb)

/home/user/Projects/env/local/lib/python2.7/site-packages/transaction-1.4.1-py2.7.egg/transaction/_transaction.py in _saveAndGetCommitishError(self)
300 import pdb
301 pdb.set_trace()
--> 302 traceback.print_stack(sys._getframe(1), None, ft)
303 # Append the stack entries from here down to the exception.
304 traceback.print_tb(tb, None, ft)

/usr/lib/python2.7/traceback.py in print_stack(f, limit, file)
267 except ZeroDivisionError:
268 f = sys.exc_info()[2].tb_frame.f_back
--> 269 print_list(extract_stack(f, limit), file)
270
271 def format_stack(f=None, limit=None):

/usr/lib/python2.7/traceback.py in print_list(extracted_list, file)
23 ' File "%s", line %d, in %s' % (filename,lineno,name))
24 if line:
---> 25 _print(file, ' %s' % line.strip())
26
27 def format_list(extracted_list):

/usr/lib/python2.7/traceback.py in _print(file, str, terminator)
11
12 def _print(file, str='', terminator='\n'):
---> 13 file.write(str+terminator)
14
15

TypeError: 'unicode' does not have the buffer interface

我发现手头的问题是,在某处,python 版本 2 与 3 不兼容,此处显示 TypeError: 'str' does not support the buffer interface .我知道 SQLAlchemy 支持 python 3+,所以这可能是问题的来源。

请注意,如果我正确地进行交易,则不会引发任何错误。

有没有办法解决这个问题而不必覆盖 traceback.py 中的代码?

最佳答案

您看到的错误不是(至少直接)由 SQLAlchemy 引起的,而是由 SQLAlchemy、IPython 以及您尝试使用的方式的组合引起的 transaction .如果您遵循这些工具的推荐用法,它就会消失。

免责声明:以下不是在 Pyramids 中使用范围 session 和 ZopeTransactionExtension 的推荐方法,但我想尽可能地坚持您提供的代码。

将它放在一个文件中,并从安装了 SQLAlchemy 的 virtualenv 中运行它,您将看到来自 SQLAlchemy 的正确错误消息:

from sqlalchemy import types
from sqlalchemy import create_engine
from sqlalchemy.schema import Column
from zope.sqlalchemy import ZopeTransactionExtension
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, scoped_session

Base = declarative_base()


class User(Base):
__tablename__ = 'user'
name = Column(types.String, primary_key=True)


def pretend_view(request):
"""Pretend view in a Pyramid application using pyramid_tm"""
import transaction
user = User()
with transaction.manager:
DBSession.add(user)
return user

if __name__ == '__main__':
engine = create_engine('sqlite://')
global DBSession
DBSession = scoped_session(
sessionmaker(extension=ZopeTransactionExtension()))
DBSession.configure(bind=engine)
Base.metadata.bind = engine
Base.metadata.create_all()
#import IPython; IPython.embed()
pretend_view("dummy request")

生成此异常: sqlalchemy.exc.IntegrityError: (IntegrityError) NOT NULL constraint failed: user.name u'INSERT INTO user DEFAULT VALUES' ()
如果您改为启动 IPython 并运行假装_ View ,您将收到您提到的 unicode 错误。

正确使用pyramid_tm

现在,如果您想在 IPython 中看到正确的错误消息,请“正确”使用 session !

通常没有理由使用 transaction在您的代码中明确显示;当 View 自动返回时(假设没有引发异常), pyramid_tm 将提交事务。这将是运行 View 的正确方法,即使在 IPython 中也会生成正确的异常:
def pretend_view(request):
"""Pretend view in a Pyramid application using pyramid_tm"""
session = DBSession() # You're using a sessionmaker, so you should make a session!
user = User()
session.add(user)
session.flush()
return user

如果您真的想从 View 中提交事务:
def pretend_view(request):
"""Pretend view in a Pyramid application using pyramid_tm"""
session = DBSession()
user = User()
session.add(user)
session.flush()
import transaction
transaction.commit()
return user

其他资源

SQLAlchemy 金字塔食谱: http://docs.pylonsproject.org/projects/pyramid/en/latest/tutorials/wiki2/index.html#bfg-sql-wiki-tutorial

pyramid_tm 文档: http://pyramid-tm.readthedocs.org/en/latest/

关于python-2.7 - SQLAlchemy 事务中的错误不会返回正确的回溯(Python 2.7),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18345322/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com