我正在使用Flask和SQLAlchemy开发一个用Python编写的现有应用程序(我没有创建此应用程序)。我需要更新刚刚超过6k的行。主表中的一行(称为SurveyRequest)具有3个指向次表(AudioRecording)的外键。我需要遍历每个SurveyRequest行,然后基于这3个ID更新相应的AudioRecording行。
对于与SQLAlchemy有关的会话工作方式,我有些困惑。
我设置了查询以返回6k结果(对此我没有任何问题),这是我需要一些帮助的循环。
我将使用这个:
query = self.session.query(SurveyRequest).filter(
SurveyRequest.audio_1 != None,
SurveyRequest.audio_2 != None,
SurveyRequest.audio_3 != None,
SurveyRequest.sent_to_transcriber == None,
SurveyRequest.created_at < before_date,
SurveyRequest.participant_id >= 100000,
SurveyRequest.participant_id < 300000,
SurveyRequest.test_number == 1
)
for sr in query.yield_per(100).enable_eagerloads(False):
我正在使用yield,因为我不希望系统将所有6k结果都加载到内存中(除非有人可以提出更好的方法?)。
因此,对于每个SurveyRequest'sr'行,我需要更新3个链接的AudioRecording行。在SurveyRequest中,三个外键是:audio_1,audio_2,audio_3。我的想法是将每个ID传递到一个单独的方法中,然后对特定的AudioRecording执行更新。我有一种感觉,如果我进行更新并提交,它将以某种方式破坏SurveyRequest查询循环。
SQLAlchemy中使用会话的方式让我感到困惑。我可以在同一会话中执行查询循环和更新吗?还是我需要为AudioRecording更新进行单独的会话?还有可能超时处理6k结果吗?
答案 0 :(得分:1)
您可能有兴趣阅读有关yield_per()
块内的数据库游标状态的以下响应:https://stackoverflow.com/a/12233167/111033
基本上,只有在完成所有结果的缓冲后才能真正提交-因此必须在循环结束时提交。
yield_per()
非常强大,可以解决很多内存管理问题,但是它非常脆弱并且有一些很大的限制,例如您发现的那个限制。