1

I'm trying to replicate the following query in SQLAlchemy + MySQL without luck...

delete paths from paths
join paths as p1 on p1.ancestor = <ID>
where paths.descendant = p1.descendant;

SQLAlchemy seems be to ignoring any joins that I put into the delete query. I also tried using a subquery instead of a join, but that's not allowed in MySQL (can't select from same table as you want to delete from). Any help would be much appreciated.

Update: Yes, I'm trying to use the ORM layer. Here's the queries that I've tried:

p1 = aliased(Path, name="p1")
db.session.query(Path).join(
    p1, p1.ancestor==<ID>
)
.filter(
    Path.descendant==p1.Path.descendant
).delete()

And the subquery variant, but this doesn't work on MySQL, so it's of no use to me:

q = db.session.query(Path.descendant).filter(Path.ancestor==<ID>).subquery()
db.session.query(Path).filter(Path.descendant.in_(q)).delete(synchronize_session='fetch')
4

2 に答える 2

2

prefixesキーワード引数を使用できます:

j = join(table1, table2, table1.c.key==table2.c.key)
stmt = delete(j, prefixes=[table1_name])
session.execute(stmt)

prefixesキーワードは、ステートメント キーワードの後に​​ 1 つまたは複数の式 (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 クエリです。

于 2016-01-18T12:12:13.980 に答える
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")を使用してカスタム構成を使用するか構築することです。

于 2013-02-24T18:29:38.713 に答える