Удаление объекта из сеанса SQLAlchemy до его сохранения

Мое приложение позволяет пользователям создавать и удалять объекты Site. Я реализовал это с помощью session.add() и session.delete(). Затем у меня есть кнопки "Сохранить" и "Reset", которые вызывают session.commit() и session.rollback().

Если я добавлю новый Site, затем сохраните/зафиксируйте его, а затем удалите его, все будет ОК. Однако, если я попытаюсь удалить объект из сеанса перед его сохранением, я получаю ошибку "не сохранялся".

код:

self.newSite = Site('foo')
self.session.add(self.newSite)
print self.session.new
self.session.delete(self.newSite)

Вывод:

IdentitySet([<Site('foo')>])

Traceback (most recent call last):
  File "C:\Program Files\Eclipse\dropins\plugins\org.python.pydev.debug_2.2.1.2011071313\pysrc\pydevd_comm.py", line 744, in doIt
    result = pydevd_vars.evaluateExpression(self.thread_id, self.frame_id, self.expression, self.doExec)
  File "C:\Program Files\Eclipse\dropins\plugins\org.python.pydev.debug_2.2.1.2011071313\pysrc\pydevd_vars.py", line 375, in evaluateExpression
    result = eval(compiled, updated_globals, frame.f_locals)
  File "<string>", line 1, in <module>
  File "C:\Python27\Lib\site-packages\sqlalchemy\orm\session.py", line 1245, in delete
    mapperutil.state_str(state))
InvalidRequestError: Instance '<Site at 0x1ed5fb0>' is not persisted

Я понимаю, что происходит здесь, но я не уверен, что я должен делать вместо этого.

Есть ли какой-нибудь другой способ удаления объекта с еще не сохраненным из сеанса? Или я должен называть session.flush() перед попыткой удаления, если объект, который я хочу удалить, еще не очищен?

Если это последний, то как приступить session.query() автофлои (чтобы ожидающие объекты отображались в результатах запроса), но session.delete() не делает (что обеспечило бы удаление отложенных объектов без ошибок).

Ответы

Ответ 1

Вы можете Session.expunge() его. Я думаю, что логическое обоснование с delete() заключается в том, что это беспокоит то, что вы не отслеживаете вещи, если отправляете их в ожидании. Но я могу видеть другую сторону этой истории, я подумаю об этом. В основном состояние, подразумеваемое delete(), включает некоторые предположения о сохранении, но они, вероятно, не так значительны, как я думаю. Затем приходит в голову метод "изгнать или удалить", что смешно, что в основном "сохранить или обновить" мы первоначально скопировали из Hibernate, который просто стал "добавлять". "add" может выполнять переходы переходных → ожидающих, а также отключенных → постоянных - может ли потенциальный "remove()" выполнять как ожидающие- > переходные и постоянные- > удаленные? слишком плохой сеанс с областью уже имеет "remove()"....

Session.query() autoflushes, потому что он собирается выйти в базу данных, чтобы испустить некоторый SQL, чтобы получить некоторые строки; так что независимо от того, что вы локально должны выходить первым. delete() просто отмечает состояние объекта, поэтому нет необходимости вызывать любой SQL. Если бы мы хотели, чтобы delete() работал в ожидании, мы просто изменим это утверждение.

Интересно, что если вы rollback() сеанс, все, что вы add() 'в этом сеансе, независимо от того, было ли оно сброшено, будет удалено.