Форум сайта python.su
0
Добрый вечер. Проблема такая: есть цикл перебора значений. Внутри этого цикла нужно вставлять строки в базу данных. Проблема в том, что после первой вставки в другую таблицу, появляется куча запросов на выборку данных. Как избежать при таком подходе кучу лишних запросов в базу данных
Код, который воспроизводит проблему:
engine = create_engine(connect_str, echo=True) Session = sessionmaker(bind=engine) for bar in default_session.query(BarLog)[:3]: conf = ManagerConfig(indicator_config='', timeframe=bar.timeframe, paper_no=1) default_session.add(conf) default_session.commit() if number == 4: break
Офлайн
33
А так:
# ... b = default_session.query(BarLog)[:3] for bar in b: # ...
Офлайн
0
Lexander
А так:
# …
b = default_session.query(BarLog)
for bar in b:
# …
Офлайн
47
коммитить наверное надо один раз после цикла
Офлайн
173
Lexander, может имели ввиду следующее:
# ... b = list(default_session.query(BarLog)[:3]) for bar in b: # ...
Отредактировано reclosedev (Авг. 30, 2013 18:06:39)
Офлайн
173
Получается, что при commit() вызывается Session.expire_all() и при доступе к атрибутам объектов, выполняется запрос. Должен помочь совет bismigalis, плюс это должно работать быстрее.
Еще есть вариант использовать возможность отсоединять объекты от сессии
session.expunge(bar) или
session.expunge_all()
Ппример на SO с expunge() для похожего случая.
Офлайн
0
Спасибо за ответы. Мне в английской группе объяснили, что после того, как делаем commit(), все объекты sqlalchemy “протухают”. Именно поэтому sqlalchemy после первого коммита лезет в базу данных, чтобы достать актуальные данные.
Для отключения такого поведения, нужно в sessionmaker передавать параметр expire_on_commit=False.
Ответ на мой вопрос в английском форуме
Офлайн