SQLAlchemy: how to remove a connection

I am having problems with this bottom with SQLAlchemy:

DELETE a FROM a INNER JOIN b ON b.`aId` = a.`Id` WHERE `b`.`xxx` = ?;

Like the post here: SQLAlchemy: create a delete query using self-learning in MySQL

I find it difficult to delete delete in SQLAlchemy with the join.

So now I do like this:

session.execute('DELETE a FROM a INNER JOIN b ON b.`aId` = a.`Id` WHERE `b`.`xxx` = %d;'%xxx)

But it just annoys me a lot, how about: SQL Injection thing, etc.

Is there a way to use SQLAlchemy to solve the problem here? Thank!

+4
source share
3 answers

If you read the documentation forsession.execute , you will see that you should do something like this:

session.execute(
    'DELETE a FROM a INNER JOIN b ON b.`aId` = a.`Id` WHERE `b`.`xxx` = :param',
    {"param": 5}
)
+3
source

SQLAlchemy 1.2 ( Postgresql, MySQL Microsoft SQL Server):

In [18]: a = table('a', column('x'))

In [19]: b = table('b', column('x'))

In [20]: c = table('c', column('x'), column('y'))

In [21]: a.delete().\
    ...:     where(a.c.x == b.c.x).\
    ...:     where(b.c.x == c.c.x).\
    ...:     where(c.c.y == 1)
Out[21]: <sqlalchemy.sql.dml.Delete object at 0x7f3577d89160>

In [22]: print(_.compile(dialect=mysql.dialect()))
DELETE FROM a USING a, b, c WHERE a.x = b.x AND b.x = c.x AND c.y = %s

Session Declarative:

In [2]: class Foo(Base):
   ...:     __tablename__ = 'foo'
   ...:     id = Column(Integer, primary_key=True)

In [3]: class Bar(Base):
   ...:     __tablename__ = 'bar'
   ...:     id = Column(Integer, primary_key=True)
   ...:     foo_id = Column(ForeignKey(Foo.id))
   ...:     

In [4]: class Baz(Base):
   ...:     __tablename__ = 'baz'
   ...:     id = Column(Integer, primary_key=True)
   ...:     bar_id = Column(ForeignKey(Bar.id))
   ...:     val = Column(Integer)
   ...:     

In [5]: session.query(Foo).\
   ...:     filter(Foo.id == Bar.foo_id,
   ...:            Bar.id == Baz.bar_id,
   ...:            Baz.val == 1).\
   ...:     delete(synchronize_session=False)
   ...:            

DELETE FROM foo USING foo, bar, baz
WHERE foo.id = bar.foo_id AND bar.id = baz.bar_id AND baz.val = %(val_1)s
+3

Here is how I did it:

map_ids = session.query(Table1.map_id). \
    filter(Table1.xxxx == 'xxx_value')

q = session.query(Table2). \
    filter(Table2.map_id.in_(map_ids.subquery()))

q.delete(synchronize_session=False)

The key point here is to create a subquery by searching for identifiers that need to be removed. Then you use the "in_" operator to select the records you want to delete. 'synchoronize_session = False' will execute the request without updating the session. This gives the best performance boost.

+2
source

All Articles