Сессия будет отслеживать все CodeSample
объекты, которые вы извлекаете. Таким образом, после итерации по 2М объектам сеанс сохраняет ссылку на все из них. Для сеанса нужны эти ссылки, чтобы он мог записать правильные изменения в базу данных на flush
. Поэтому я верю, что то, что вы видите, следует ожидать.
Чтобы одновременно хранить в памяти только N объектов, вы можете сделать что-то вроде приведенного ниже кода (вдохновленный этим ответом , заявление об отказе от ответственности: я не проверял это).
offset = 0
N = 10000
got_rows = True
while got_rows:
got_rows = False
for sample in session.query(CodeSample).limit(N).offset(offset):
got_rows = True
for proj in projects:
if sample.filename.startswith(proj.abs_source):
sample.filename = "some other path"
offset += N
session.flush() # writes changes to DB
session.expunge_all() # removes objects from session
Но вышесказанное немного неуклюже, возможно, некоторые гуру SQLAlchemy знает, как лучше это сделать.
Кстати, вам не нужен session.add (), сессия отслеживает изменения объектов. Почему вы используете yield_per
( РЕДАКТИРОВАТЬ: Я полагаю, это для получения строк в кусках из БД, это правильно? Сеанс все равно будет отслеживать их все.)
EDIT:
Хм, похоже, что-то я неправильно понял. От Документы :
weak_identity_map:
При значении по умолчанию True используется карта со слабой ссылкой;
случаи, которые не являются внешне
ссылка будет сборка мусора
немедленно. Для разыменованных
экземпляры с ожидающими изменениями
настоящее, атрибут управления
Система создаст временную
сильная ссылка на объект, который
длится, пока изменения не сбрасываются в
база данных, в этот момент это
снова разыменованный. С другой стороны,
при использовании значения False,
Карта идентичности использует обычный Python
словарь для хранения экземпляров.
сеанс будет поддерживать все экземпляры
присутствовать, пока они не будут удалены с помощью
expunge (), clear () или purge ().
и
prune (): удаляет ссылки на экземпляры, кэшированные в карте идентификации.
Обратите внимание, что этот метод имеет смысл только в том случае, если для «weak_identity_map» задано значение False. Слабая карта идентичности по умолчанию является самонастраивающейся.
Удаляет любой объект в карте идентификации этого сеанса, на который нет ссылок в коде пользователя, который был изменен, добавлен или запланирован для удаления. Возвращает количество обрезанных объектов.