65

I have a table that has millions of rows. I want to delete multiple rows via an in clause. However, using the code:

session.query(Users).filter(Users.id.in_(subquery....)).delete()

The above code will query the results, and then execute the delete. I don't want to do that. I want speed.

I want to be able to execute (yes I know about the session.execute):Delete from users where id in ()

So the Question: How can I get the best of two worlds, using the ORM? Can I do the delete without hard coding the query?

supreme Pooba
  • 868
  • 1
  • 7
  • 14

4 Answers4

74

Yep! You can call delete() on the table object with an associated where clause.

Something like this:

stmt = Users.__table__.delete().where(Users.id.in_(subquery...))

(and then don't forget to execute the statement: engine.execute(stmt))

source

MarredCheese
  • 17,541
  • 8
  • 92
  • 91
dizzyf
  • 3,263
  • 19
  • 29
48

To complete dizzy's answer:

delete_q = Report.__table__.delete().where(Report.data == 'test')
db.session.execute(delete_q)
db.session.commit()
Mickael
  • 829
  • 7
  • 9
30

The below solution also works, if developers do not want to execute a plain vanilla query.

session.query(Users).filter(Users.id.in_(subquery....)).delete(synchronize_session=False)
bertdida
  • 4,988
  • 2
  • 16
  • 22
Ojus sangoi
  • 636
  • 7
  • 7
  • 2
    What is that `synchronize_session=False` for? – Nam G VU Aug 03 '21 at 06:05
  • 2
    @NamGVU Here is the explanation from the documentation: False - don’t synchronize the session. This option is the most efficient and is reliable once the session is expired, which typically occurs after a commit(), or explicitly using expire_all(). Before the expiration, objects that were updated or deleted in the database may still remain in the session with stale values, which can lead to confusing results. https://docs.sqlalchemy.org/en/14/orm/session_basics.html#selecting-a-synchronization-strategy – Ojus sangoi Aug 03 '21 at 08:37
15

New syntax (1.4 version and above)

from sqlalchemy import delete

statement = delete(User).where(User.id.in_(...))
session.execute(statement)

https://docs.sqlalchemy.org/en/14/core/dml.html?highlight=delete

wim
  • 338,267
  • 99
  • 616
  • 750
Angel
  • 1,959
  • 18
  • 37