我目前正在尝试将我的数据库表从MyISAM移到InnoDB。我在服务器上运行的请求和cron作业有时间问题导致一些错误。我很确定交易支持会帮助我解决问题。因此,我正在过渡到InnoDB。
我有一套测试,可以调用我们的webservices REST API并接收XML响应。测试套件相当彻底,它是用Python编写的,并使用SQLAlchemy来查询数据库中的信息。但是,当我将系统中的表从MyISAM更改为InnoDB时,测试开始失败。但是,测试没有失败,因为系统不工作,它们失败,因为ORM没有正确查询我正在测试的数据库中的行。当我单步执行代码时,我看到了正确的结果,但ORM根本没有返回正确的结果。
基本流程是:
class UnitTest(unittest.TestCase):
def setUp(self):
# Create a test object in DB that gets affected by the web server
testObject = Obj(foo='one')
self.testId = testObject.id
session.add(testObject)
session.commit()
def tearDown(self):
# Clean up after the test
testObject = session.query(Obj).get(self.testId)
session.delete(testObject)
session.commit()
def test_web_server(self):
# Ensure the initial state of the object.
objects = session.query(Obj).get(self.testId)
assert objects.foo == 'one'
# This will make a simple HTTP get call on an url that will modify the DB
response = server.request.increment_foo(self.testId)
# This one fails, the object still has a foo of 'one'
# When I stop here in a debugger though, and look at the database,
# The row in question actually has the correct value in the database.
# ????
objects = session.query(Obj).get(self.testId)
assert objects.foo == 'two'
使用MyISAM表存储对象,此测试将通过。但是,当我更改为InnoDB表时,此测试将无法通过。更有趣的是,当我逐步调试调试器中的代码时,我可以看到数据库符合我的预期,因此它不是Web服务器代码中的问题。我几乎尝试了expire_all,autoflush,autocommit等的所有组合,但仍然无法通过这个测试。
如有必要,我可以提供更多信息。
谢谢, 康拉德
答案 0 :(得分:1)
问题是你在将新对象添加到会话,刷新和SQLAlchemy为其分配ID之前放置了行self.testId = testObject.id
。因此,self.testId
始终为None
。将此行移至session.commit()
下方。