db.refresh()
在 SQLAlchemy 中,db.refresh()
?用于從數據庫中重新加載對象的狀態,確保對象屬性與數據庫中的實際數據保持一致。下面詳細介紹其使用場景和作用:
1.獲取數據庫生成的值
當數據庫自動生成字段(如自增 ID、默認值、觸發器計算的值)時,refresh
?可獲取這些值:
user = User(name="Alice")
db.add(user)
db.commit()
db.refresh(user) # 獲取數據庫分配的自增 ID
print(user.id) # 此時 ID 已從數據庫加載
2.?確保讀取最新數據
若其他事務可能修改了數據,可通過?refresh
?強制獲取最新狀態:
# 用戶 A 修改了數據
# 用戶 B 需要獲取最新狀態
db.refresh(user)
print(user.status) # 獲取數據庫中最新的狀態
3.?處理數據庫觸發器或默認值
當字段由數據庫觸發器或默認值自動填充時:
class Order(Base):__tablename__ = "orders"id = Column(Integer, primary_key=True)created_at = Column(DateTime, server_default=func.now()) # 數據庫默認值order = Order()
db.add(order)
db.commit()
db.refresh(order) # 獲取數據庫生成的 created_at
print(order.created_at) # 顯示數據庫實際生成的時間
為何不需要?db.refresh()
提交后對象已同步:
db.commit()
?會將所有掛起的更改寫入數據庫,并更新對象狀態。因此,提交后對象屬性已經反映了最新值,無需刷新。無外部修改:
任務在單個事務中執行,且沒有其他進程或線程修改同一對象,因此對象狀態始終是一致的。refresh
?的適用場景:db.refresh()
?主要用于以下情況:讀取數據庫生成的值(如自增 ID、默認值)。
確認其他事務對數據的修改。
強制刷新延遲加載的關聯對象。
?適用場景:
1.讀取數據庫生成的值,比如自增ID
2.有外部修改需要刷新確認,比如有其他進程修改同一對象。
db.rollback()
db.rollback()
?回滾范圍:
- 最近一次?
db.commit()
?之后(如果有提交過)。 - 事務開始點(如果從未提交)。
解釋:
db.rollback()
?的回滾范圍取決于數據庫事務的邊界和當前會話的狀態。具體來說,它會撤銷自當前事務開始以來所有未提交的數據庫操作。
在關系型數據庫中,事務是一組不可分割的操作序列,要么全部成功,要么全部失敗。db.rollback()
?的作用是:
- 撤銷未提交的更改:將數據庫狀態恢復到事務開始前的狀態。
- 釋放事務鎖:如果操作涉及鎖(如寫操作),回滾后會釋放這些鎖。
- 清空會話緩存:SQLAlchemy 會話中未提交的對象更改會被丟棄。
db.rollback():
- 每次?
db.commit()
?后:事務結束,數據已永久保存,后續的?db.rollback()
?不會影響已提交的數據。 - 異常發生時:
db.rollback()
?會撤銷自最近一次提交以來的所有操作。
例子:
1.如果在第一次?db.commit()?之前發生異常(例如查詢失敗):回滾到事務開始點(無實際影響,因為尚未提交任何更改)。
2. 如果在第一次?db.commit()?之后、第二次?db.commit()?之前發生異常(例如?get_markdown?失敗):回滾?structure?的更新和?status=success?的更改,但?status=running?已提交,不受影響。
3.如果在第二次?db.commit()?之后發生異常(幾乎不可能,因為已返回):不會觸發此回滾。
?