遍历超过6k的结果,想要更新链接表,担心花费的时间

时间:2019-05-13 04:50:38

标签: python sqlalchemy flask-sqlalchemy

我正在使用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结果吗?

1 个答案:

答案 0 :(得分:1)

您可能有兴趣阅读有关yield_per()块内的数据库游标状态的以下响应:https://stackoverflow.com/a/12233167/111033

基本上,只有在完成所有结果的缓冲后才能真正提交-因此必须在循环结束时提交。

yield_per()非常强大,可以解决很多内存管理问题,但是它非常脆弱并且有一些很大的限制,例如您发现的那个限制。