2017-08-23 58 views
0

我在我的DB(postgresql 9.5)中有2個sqlalchemy模型。SqlAlchemy鎖定2個表中的外部行

class AModel(Model): 
    id = db.Column(db.Integer, primary_key=True) 

class BModel(Model): 
    id = db.Column(db.Integer, primary_key=True) 
    a_id = db.Column(db.ForeignKey('amodel.id'), index=True) 
    a = db.relationship('AModel', backref=db.backref('bmodel')) 

現在我想鎖更新記錄BModel(但我也想從AModel表鎖相關的行,這樣就不會被其他進程編輯)。

我可以鎖定模型BModel

db.session(BModel).query.with_for_update().filter(BModel.id == id).first() 

但有可能在一個語句來鎖定相關模型AModel?或者我需要鎖定第二個記錄的明確性,即使我不更新它?

+0

你在用什麼數據庫? –

+0

我正在使用postgresql 9.5和python 3.6 – Blejwi

回答

1

如果你想同時鎖定兩個錶行,他們一起在你的SELECT ... FOR UPDATE語句:

db.session.query(BModel).\ 
    join(Bmodel.a).\ 
    with_for_update().\ 
    filter(BModel.id == id).\ 
    first() 

在單證上locking clause指出,除非有具體的表命名爲OF table_name [, ...],所有表都受到影響:

如果在鎖定子句中命名了特定的表,那麼只有來自這些表的行被鎖定;像往常一樣讀取SELECT中使用的任何其他表。沒有表列表的鎖定子句會影響語句中使用的所有表。如果鎖定子句應用於視圖或子查詢,則會影響視圖或子查詢中使用的所有表。但是,這些子句不適用於主查詢引用的WITH查詢。如果要在WITH查詢中發生行鎖定,請在WITH查詢中指定鎖定子句。

是否需要鎖定AModel中的行取決於您在做什麼。如果你不使用AModel的值,而且你沒有更新AModel本身,你可能不需要鎖定。

+0

Works。感謝您的幫助,我實際上需要鎖定它以防止其他線程的更新。 – Blejwi