Удаление объекта из сеанса 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()
'в этом сеансе, независимо от того, было ли оно сброшено, будет удалено.