我试图在SQLAlchemy + MySQL中复制以下查询而没有运气......
delete paths from paths
join paths as p1 on p1.ancestor = <ID>
where paths.descendant = p1.descendant;
SQLAlchemy似乎忽略了我在删除查询中添加的任何联接。我也尝试使用子查询而不是连接,但是在MySQL中不允许这样做(不能从你想要删除的同一个表中选择)。任何帮助将不胜感激。
更新: 是的,我正在尝试使用ORM层。这是我尝试过的查询:
p1 = aliased(Path, name="p1")
db.session.query(Path).join(
p1, p1.ancestor==<ID>
)
.filter(
Path.descendant==p1.Path.descendant
).delete()
和子查询变体,但这对MySQL不起作用,所以对我没用:
q = db.session.query(Path.descendant).filter(Path.ancestor==<ID>).subquery()
db.session.query(Path).filter(Path.descendant.in_(q)).delete(synchronize_session='fetch')
答案 0 :(得分:2)
SQLAlchemy目前支持Postgresql,MySQL和其他版本的UPDATE..FROM,但我们还没有尝试过支持DELETE..JOIN。
但是,就生成SQL字符串而言,它似乎确实有效(几乎?):
class Path(Base):
__tablename__ = "path"
id = Column(Integer, primary_key=True)
descendant = Column(Integer)
ancestor = Column(Integer)
j = join(Path, p1, p1.ancestor == 5)
d = delete(j).where(Path.descendant == p1.descendant)
print d
打印:
DELETE FROM path JOIN path AS p1 ON p1.ancestor = :ancestor_1
WHERE path.descendant = p1.descendant
然而,我的MySQL数据库不接受这个,默认情况下它会渲染INNER JOIN,但是如果我修改MySQL编译器没有这样做,仍然会失败:
s.execute(d)
(ProgrammingError) (1064, "You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the
right syntax to use near 'JOIN path AS p1 ON p1.ancestor = 5 WHERE
path.descendant = p1.descendant' at line 1") 'DELETE FROM path JOIN
path AS p1 ON p1.ancestor = %s WHERE path.descendant = p1.descendant'
(5,)
看起来像你的SQL逐字(哦,除了'删除路径来自路径'?是吗?)?
在任何情况下,如果内置编译器没有这样做,您的选择是使用session.execute("some sql")
或使用compiler extension构建自定义构造。
答案 1 :(得分:2)
您可以使用prefixes
关键字参数:
j = join(table1, table2, table1.c.key==table2.c.key)
stmt = delete(j, prefixes=[table1_name])
session.execute(stmt)
prefixes
关键字只是在statement关键字后添加一个或多个表达式,即SELECT,INSERT,UPDATE或DELETE。
在这种情况下,delete(j)
语句生成表达式:"DELETE FROM table1 INNER JOIN table2 ON table1.key=table2.key"
。
当我们添加prefixes
参数表达式变为:"DELETE table1 FROM table1 INNER JOIN table2 ON table1.key=table2.key"
时,这是正确的MySQL查询。