我已经构建了一个大型Flask应用程序,并且已经运行了几年连续的单元测试。最近,我开始看到抛出以下错误:
InvalidRequestError: This Session's transaction has been rolled back due to a previous exception during flush.
看来sqlalchemy在拆解期间没有正确释放会话,这很奇怪,因为应用程序中没有任何内容发生变化?当我尝试重新运行单元测试并在数据库中具有相同的唯一条目时,就会发生这种情况。例如,为了测试,我用包含用户的测试数据填充数据库(具有唯一的电子邮件,用户名);我第一次运行单元测试时它有效,但第二次失败。
这让我相信这是一个会话拆解的问题,我不太了解它?
class CredentialsTestCase(unittest.TestCase):
def setUp(self):
self.app = create_app("testing")
self.app_context = self.app.app_context()
self.app_context.push()
db.drop_all()
db.create_all()
Role.insert_roles()
self.client = self.app.test_client(use_cookies=True)
def tearDown(self):
db.session.remove()
db.drop_all()
self.app_context.pop()
def test_auth(self):
r = Role.query.filter_by(name="User").first()
u = User(email="testemail@test.com", username="testuser", role=r)
db.session.add(u)
db.session.commit()
TESTING=True
WTF_CSRF_ENABLED=False
PRESERVE_CONTEXT_ON_EXCEPTION=False
SQLALCHEMY_DATABASE_URI='random-name-for-db.sqlite'
如果任何其他代码相关,我可以通过编辑添加。
添加了完整的追溯功能。另外值得注意的是,测试数据库是sqlite,而生产是MySQL。
ERROR: test_authentication_protocols (test_api_1_0.CredentialsModelTestCase)
Check authentication and credentials
Traceback (most recent call last):
File "/Users/dh/Documents/GitHub/web-tata/web-tata/tests/test_api_1_0.py" line 77, in test_authentication_protocols
db.session.commit()
File "/Users/dh/Documents/GitHub/web-tata/web-tata/flask/lib/python2.7/site-packages/sqlalchemy/orm/scoping.py", line 157, in do
return getattr(self.registry(), name)(*args, **kwargs)
File "/Users/dh/Documents/GitHub/web-tata/web-tata/flask/lib/python2.7/site-packages/sqlalchemy/orm/session.py", line 874, in commit
self.transaction.commit()
File "/Users/dh/Documents/GitHub/web-tata/web-tata/flask/lib/python2.7/site-packages/sqlalchemy/orm/session.py", line 461, in commit
self._prepare_impl()
File "/Users/dh/Documents/GitHub/web-tata/web-tata/flask/lib/python2.7/site-packages/sqlalchemy/orm/session.py", line 441, in _prepare_impl
self.session.flush()
File "/Users/dh/Documents/GitHub/web-tata/web-tata/flask/lib/python2.7/site-packages/sqlalchemy/orm/session.py", line 2139, in flush
self._flush(objects)
File "/Users/dh/Documents/GitHub/web-tata/web-tata/flask/lib/python2.7/site-packages/sqlalchemy/orm/session.py", line 2259, in _flush
transaction.rollback(_capture_exception=True)
File "/Users/dh/Documents/GitHub/web-tata/web-tata/flask/lib/python2.7/site-packages/sqlalchemy/util/langhelpers.py", line 66, in exit
compat.reraise(exc_type, exc_value, exc_tb)
File "/Users/dh/Documents/GitHub/web-tata/web-tata/flask/lib/python2.7/site-packages/sqlalchemy/orm/session.py", line 2223, in _flush
flush_context.execute()
File "/Users/dh/Documents/GitHub/web-tata/web-tata/flask/lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.py", line 389, in execute
rec.execute(self)
File "/Users/dh/Documents/GitHub/web-tata/web-tata/flask/lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.py", line 548, in execute
uow
File "/Users/dh/Documents/GitHub/web-tata/web-tata/flask/lib/python2.7/site-packages/sqlalchemy/orm/persistence.py", line 181, in save_obj mapper, table, insert)
File "/Users/dh/Documents/GitHub/web-tata/web-tata/flask/lib/python2.7/site-packages/sqlalchemy/orm/persistence.py", line 835, in _emit_insert_statements
execute(statement, params)
File "/Users/dh/Documents/GitHub/web-tata/web-tata/flask/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 945, in execute
return meth(self, multiparams, params)
File "/Users/dh/Documents/GitHub/web-tata/web-tata/flask/lib/python2.7/site-packages/sqlalchemy/sql/elements.py", line 263, in _execute_on_connection
return connection._execute_clauseelement(self, multiparams, params)
File "/Users/dh/Documents/GitHub/web-tata/web-tata/flask/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 1053, in _execute_clauseelement
compiled_sql, distilled_params
File "/Users/dh/Documents/GitHub/web-tata/web-tata/flask/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 1189, in _execute_context
context)
File "/Users/dh/Documents/GitHub/web-tata/web-tata/flask/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 1402, in _handle_dbapi_exception
exc_info
File "/Users/dh/Documents/GitHub/web-tata/web-tata/flask/lib/python2.7/site-packages/sqlalchemy/util/compat.py", line 203, in raise_from_cause
reraise(type(exception), exception, tb=exc_tb, cause=cause)
File "/Users/dh/Documents/GitHub/web-tata/web-tata/flask/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 1182, in _execute_context
context)
File "/Users/dh/Documents/GitHub/web-tata/web-tata/flask/lib/python2.7/site-packages/sqlalchemy/engine/default.py", line 470, in do_execute
cursor.execute(statement, parameters)
File "/Users/dh/Documents/GitHub/web-tata/web-tata/flask/lib/python2.7/site-packages/MySQLdb/cursors.py", line 205, in execute
self.errorhandler(self, exc, value)
File "/Users/dh/Documents/GitHub/web-tata/web-tata/flask/lib/python2.7/site-packages/MySQLdb/connections.py", line 36, in defaulterrorhandler
raise errorclass, errorvalue
IntegrityError: (_mysql_exceptions.IntegrityError) (1062, "Duplicate entry 'test@user44457.com' for key 'ix_users_email'") [SQL: u'INSERT INTO users (email, username, confirmed, _password_hash, otp_secr
et, member_since, last_seen, role_id) VALUES (%s, %s, %s, %s, %s, %s, %s, %s)'] [parameters: ('test@user44457.com', 'testuser75', 1, 'pbkdf2:sha256:50000$zkYlgQKg$06b586db3c86c2bc5e3511b5710d9119ae65996
16d4785cd2d35e022b4152fea', 'WWGOWIJWJ7S4ZN3I', datetime.datetime(2017, 4, 10, 16, 42, 50, 115277), datetime.datetime(2017, 4, 10, 16, 42, 50, 115294), 3L)]