回答

收藏

具有多列的 SQLAlchemy 相关更新?

技术问答 技术问答 487 人阅读 | 0 人回复 | 2023-09-12

Acorrelated update根据另一个表中的值更新一个表中的所有行,同时将两个表链接在一起。" ^! Y! U: z* Z1 {% \
从SQLAlchemy docs 中,我们可以很容易地进行相关的更新,但只能在单列中进行:
* q" E1 ]# R- z5 Kupdate(foo).values(bar=select([foobar.c.bar]).where(foobar.c.id == foo.c.id))这转化为:1 o! Z& h5 h9 U6 ?& K# F4 k1 U
UPDATE fooSET bar =  SELECT bar    FROM foobar    WHERE foobar.id = foo.id) 如何在 sqlalchemy 用多列编写相关更新?
% H+ i" x% E" X( |. u% Q, Z* K* wUPDATE fooSET (bar,baz) =  SELECT bar,baz    FROM foobar    WHERE foobar.id = foo.id)                 
2 U1 `% J) L* J& o; }2 ]9 C    解决方案:                                                                ' M9 E6 F. T0 d: L! a
                                                                根据你的头像和描述,我猜你在用 Oracle。以下 可用于此答案SQLAlchemy concotion,如果您的连接结果是按键保留视图:* }, U+ l8 g9 C5 t" |2 X
stmt = select([foo.c.bar.label('foo_bar        foo.c.baz.label('foo_baz        foobar.c.bar.label('foobar_bar        foobar.c.baz.label('foobar_baz')]).\    where(foo.c.id == foobar.c.id)update(stmt).values({stmt.c.foo_bar: stmt.c.foobar_bar,                    stmt.c.foo_baz: stmt.c.foobar_baz})它产生以下 SQL:
9 o: n8 s% D" G! N3 ~3 ?4 w( I7 `UPDATE (SELECT foo.bar AS foo_bar,              foo.baz AS foo_baz,              foobar.bar AS foobar_bar,              foobar.baz AS foobar_baz        FROM foo,foobar        WHERE foo.id = foobar.id)SET foo_bar=foobar_bar,foo_baz=foobar_baz由于您的表共享列名,标签非常重要。
& X# e3 f. i' y. e  c4 Y也可以生成原始目标 SQL:
( I: \* q# R5 J& b8 U7 s- \, \from sqlalchemy import tuple_,select,existsstmt = select([foobar.c.bar,foobar.c.baz]).where(foo.c.id == foobar.c.id)foo.update().\    values({tuple_(foo.c.bar,foo.c.baz).self_group(): stmt}).\    where(exists(stmt))该self_group()电话很重要,因为编译器似乎忽略了周围的元组括号,产生了不正确的语法。我加了 WHERE 子句避免更新不匹配foobar的foo行:
* M  u8 I  o( S. c. JUPDATE foo SET (bar,baz)=(SELECT foobar.bar,foobar.baz FROM foobar WHERE foo.id = foobar.id) WHERE EXISTS (SELECT foobar.bar,foobar.baz FROM foobar WHERE foo.id = foobar.id)
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则