2015-10-15 65 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)