2015-10-15 53 views
5

使用MySQL,我想生成這個SQL通過SQLAlchemy的ORM連接表產生的這個(多表更新,沒有加入的條件,這是不是我想要的):更新使用session.query

UPDATE tableA, tableB 
SET tableA.foo = 1 
WHERE tableB.bar IN ('baz','baaz') 

我試圖改變.J oin轉換成另一個.filter來指定連接條件,但這並未解決問題。 我該如何強制這個簡單的更新語句來進行正確的連接?

+0

你解決了這個問題嗎?我有幾乎相同的東西,我正在努力 – Fuxi

+0

只好繼續解決方法(兩個查詢,而不是一個)。如果你正在與同樣的問題苦苦掙扎,請提出問題,也許有人會看到它。 – ValAyal

回答

3

隨着0.7.4版本sqlalchemy.sql.expression.update並允許引用到多個表的WHERE子句。有了這個,你可以建立並執行類似的表達式:(從上面的鏈接直例子)

users.update().values(name='ed').where(
     users.c.name==select([addresses.c.email_address]).\ 
        where(addresses.c.user_id==users.c.id).\ 
        as_scalar() 
     ) 

ValAyal遇到的問題是實際上是因爲Query.join()沒有與Query.update()支持。不幸的是,在0.9.1之前,這是默默地產生像上面分享的一個ValAyal一樣的查詢。該changelog notes for 0.9.1指出,行爲進行了修改,發出警告:

[ORM] [錯誤]查詢不支持聯接,子查詢,或特殊FROM子句 使用Query.update()或查詢時。 delete()方法;如果Query.join() 或Query.select_from()等方法被調用,則會發出警告,而不是默默忽略這些字段。從 1.0.0b5開始,這將引發錯誤。

參考文獻:#3349

實際上,我們遇到了這個,我只是今天晚上上班,發現我們的代碼,實際上,發出如下警告(其中表示,將在1.0的誤差):

SAWarning: Can't call Query.update() or Query.delete() when join(), outerjoin(), select_from(), or from_self() has been called. This will be an exception in 1.0 
    self._validate_query_state() 

在我們的案例中,我們選擇將更新轉換爲select和更新到一個表。

+0

請注意,此處的示例不是多表更新,而是使用子查詢引用多個表的標準SQL方式。 –

0

我想我有完全相同的問題。這裏是我的解決方案:

query = update(Model).values(field=123) 
query = query.where(Model.parent_model_id == ParentModel.id) 
query = query.where(ParentModel.grand_parent_id == GrandParentModel.id) 
query = query.where(GrandParentModel.name == 'foobar') 
session.execute(query)