Python 使用ThreadPoolExecutor时在Django测试中保存到数据库
我在尝试使用Django的测试用例测试与ThreadPoolExecutor并行的代码时遇到了一个问题。在服务器上,一切正常(到目前为止,至少没有已知的问题“手动”测试),但当我运行测试时,它们的执行只是停留在save()方法上。 所以,基本上我有这样的东西:Python 使用ThreadPoolExecutor时在Django测试中保存到数据库,python,django,postgresql,concurrency,django-testing,Python,Django,Postgresql,Concurrency,Django Testing,我在尝试使用Django的测试用例测试与ThreadPoolExecutor并行的代码时遇到了一个问题。在服务器上,一切正常(到目前为止,至少没有已知的问题“手动”测试),但当我运行测试时,它们的执行只是停留在save()方法上。 所以,基本上我有这样的东西: class A(models.Model): # something here def start(self): objectsB = [] for i in range(n):
class A(models.Model):
# something here
def start(self):
objectsB = []
for i in range(n):
objectB = B(i)
objectsB.append(objectB)
results = []
with concurrent.futures.ThreadPoolExecutor(max_workers=len(objectsB)) as executor:
futures = [executor.submit(objectB.start) for objectB in objectsB]
for future in concurrent.futures.as_completed(futures):
results.append(future.result())
return results
class B(models.Model):
# something here
def start(self):
# some logic here (including reading from database)
response = requests.post('http://www.externalapi.com')
# some logic here
print('during test this is printed')
self.save()
print('during test this is never reached')
当我在没有并发性的情况下使用相同的代码时,只需按顺序执行
objectB.start
,测试工作正常。在objectsB的方法start
中读取对数据库的调用似乎也起作用。我使用Django 1.9、python 3.5、postgresql 9.5.3和nose来运行测试。任何关于这种方法可能错误的帮助或想法都将不胜感激。如果没有实际的代码,很难说发生了什么,但我猜您的数据库事务中会遇到死锁。Django的TestCase
运行事务中的每个测试用例。您可以尝试使用TransactionTestCase
测试事务敏感代码。如果这不能解决问题,我需要更多关于实际代码的信息。谢谢,@knbk。我没有提供实际的代码,因为它会占用太多的空间,而问题的范围似乎仅限于B的start
。此外,如果我从那里删除所有逻辑,只留下self.save()
,问题仍然存在。从TransactionTestCase而不是TestCase子类化我的测试用例类可以使测试顺利通过。但是现在在销毁数据库阶段的所有测试之后,我经常从postgresql得到一个错误,说它正在另一个地方使用。我遇到了同样的问题,并用TransactionTestCase
解决了这个问题,如其他注释中所述。需要指出的一个问题是:“迁移中加载的任何初始数据将仅在TestCase
测试中可用,而不在TransactionTestCase
测试中可用。”。如果需要解决此问题,可以设置serialized\u rollback=True
。