Есть ли порядок добавления или удаления при фиксации в sqlalchemy
Я добавляю кучу записей в таблицу в sqlalchemy. Если запись уже существует на основе некоторого ключа, я удаляю строку в таблице, а затем добавляю "обновленную" запись. После завершения удаления и добавления всех записей я фиксирую сеанс. Однако во время тестирования фиксация не выполняется из-за сбоя уникального ограничения. Насколько я понимаю из этой ошибки, я пытаюсь добавить обновленную запись перед удалением старой записи. Если я удалю старую запись, затем зафиксирую, а затем добавлю, все работает нормально.
Итак, мой вопрос: есть ли в sqlalchemy определенный порядок операций для удаления и добавления? Можно ли изменить этот порядок? Просматривая свой код, я заметил, что объект, который я добавляю, создается дважды, но добавляется только один раз (см. Ниже) - возможно, это проблема (но не уверен, почему это так).
Мне также не нужен commit(), потому что я хочу выполнить фиксацию только в том случае, если я добавлю / обновлю все записи.
#Inside a loop
#-----------------------
temp_doc = Document(doc)
dirty_doc = session.query(Document).filter(Document.local_id == temp.local_id).first()
#other non-relevant code here ...
session.delete(dirty_doc)
#This seems to be needed but I wouldn't expect it to be
session.commit()
#Later on in the code ...
if add_new_doc:
temp_doc = Document(doc)
session.add(temp_doc)
#Outside the loop
#-----------------------------
session.commit()
session.close()
1 ответ
Здесь был задан аналогичный, но другой вопрос относительно того, поддерживается ли порядок в добавленных объектах: сохраняет ли SQLAlchemy порядок при добавлении объектов в сеанс?
Это побудило взглянуть на код сеанса, так как я не видел документации по поведению сброса.
Ссылка на код сеанса: https://github.com/sqlalchemy/sqlalchemy/blob/master/lib/sqlalchemy/orm/session.py
Искать def _flush(self
В коде похоже, что добавления и обновления выполняются перед удалением, что объясняет, почему я столкнулся с моей проблемой.
В качестве исправления я теперь промываю, а не фиксирую (внутри цикла), что, похоже, решает проблему. Я предполагаю, что порядок сброса сохраняется, т. Е. Команды, которые сначала сбрасываются, сначала фиксируются / сохраняются.