Ứng dụng của tôi cho phép người dùng tạo và xóa các đối tượng Site
. Tôi đã triển khai điều này bằng cách sử dụng session.add()
và session.delete()
. Sau đó tôi có các nút 'Lưu' và 'Đặt lại' gọi session.commit()
và session.rollback()
.Xóa một đối tượng khỏi phiên SQLAlchemy trước khi nó được lưu giữ
Nếu tôi thêm Site
mới, sau đó lưu/cam kết và sau đó xóa, mọi thứ sẽ ổn. Tuy nhiên, nếu tôi cố xóa một đối tượng khỏi phiên trước khi nó được lưu, tôi sẽ nhận được lỗi 'không được duy trì'.
Code:
self.newSite = Site('foo')
self.session.add(self.newSite)
print self.session.new
self.session.delete(self.newSite)
Output:
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
tôi hiểu những gì đang xảy ra ở đây, nhưng tôi không chắc chắn những gì tôi nên làm để thay thế.
Có phương pháp nào khác để xóa đối tượng chưa tồn tại khỏi phiên không? Hoặc tôi có nên gọi session.flush()
trước khi thử xóa, trong trường hợp đối tượng tôi muốn xóa chưa được xóa chưa?
Nếu đó là sau, cách tự động xóa (đảm bảo rằng các đối tượng đang chờ hiển thị trong kết quả truy vấn), nhưng session.delete()
không (đảm bảo rằng các đối tượng đang chờ xử lý có thể bị xóa mà không có lỗi).
Tôi đồng ý với Mike rằng 'xóa' có thể tha thứ hơn. Tuy nhiên, tình hình hiện tại được đơn giản hóa nhiều - có thể có các đối tượng liên quan khác được rõ ràng hoặc ngầm (thông qua quan hệ) được thêm vào cùng một phiên và không được cam kết. Vì vậy, IMO, cách sạch nhất là thực hiện một 'rollback()' trên phiên làm việc. – van
Cảm ơn, điều đó có ý nghĩa bây giờ. Vì vậy, khi nút xóa được nhấp, logic nên là gì? Một cái gì đó như 'try: session.delete (foo); ngoại trừ InvalidRequestError: session.expunge (foo) '? Hoặc, theo [câu trả lời này] (http://stackoverflow.com/a/3897845/665488), có thể: 'if has_identity (foo): session.delete (foo); else: session.expunge (foo) '? –
Tôi có thể nói "nếu đối tượng trong phiên.new: expunge else: delete" – zzzeek