Перебирая более 6 тыс. Результатов, хочу обновить связанную таблицу, беспокоюсь о затраченном времени - PullRequest
0 голосов
/ 13 мая 2019

Я работаю над уже существующим приложением, написанным на Python, используя Flask и SQLAlchemy (я не создавал это приложение).Мне нужно обновить чуть более 6 тысяч строк.Строка из основной таблицы (называемая SurveyRequest) имеет 3 внешних ключа, которые указывают на дополнительную таблицу (AudioRecording).Мне нужно просмотреть каждую строку SurveyRequest, а затем, основываясь на этих 3 идентификаторах, обновить соответствующую строку 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 3 внешних ключа: аудио_1, аудио_2, аудио_3.Моя идея состоит в том, чтобы передать каждый идентификатор в отдельный метод, который затем выполнит обновление, которое мне нужно сделать для этой конкретной AudioRecording.У меня есть ощущение, что если я сделаю обновления и зафиксирую, это каким-то образом нарушит цикл запросов SurveyRequest.

То, как сеанс используется в SQLAlchemy, меня немного смущает.Можно ли выполнять циклы запросов и обновления в одном сеансе?Или мне нужно сделать отдельный сеанс для обновлений AudioRecording?Также возможен ли тайм-аут для обработки результатов 6 КБ?

1 Ответ

1 голос
/ 14 мая 2019

Вам может быть интересно прочитать этот ответ о состоянии курсора вашей базы данных в блоке yield_per(): https://stackoverflow.com/a/12233167/111033

По сути, вы не можете выполнить фиксацию, пока не закончите буферизацию всех результатов, поэтому вы должны выполнить фиксацию в конце цикла.

yield_per() очень мощный и может решить множество проблем управления памятью, однако он довольно хрупкий и имеет некоторые довольно большие ограничения, такие как тот, который вы обнаружили.

...