Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to delete rows from a table using an SQLAlchemy query without ORM?

I'm writing a quick and dirty maintenace script to delete some rows and would like to avoid having to bring my ORM classes/mappings over from the main project. I have a query that looks similar to:

address_table = Table('address',metadata,autoload=True) addresses = session.query(addresses_table).filter(addresses_table.c.retired == 1) 

According to everything I've read, if I was using the ORM (not 'just' tables) and passed in something like:

addresses = session.query(Addresses).filter(addresses_table.c.retired == 1) 

I could add a .delete() to the query, but when I try to do this using only tables I get a complaint:

File "/usr/local/lib/python2.6/dist-packages/sqlalchemy/orm/query.py", line 2146, in delete     target_cls = self._mapper_zero().class_ AttributeError: 'NoneType' object has no attribute 'class_' 

Which makes sense as its a table, not a class. I'm quite green when it comes to SQLAlchemy, how should I be going about this?

like image 634
John Carter Avatar asked Mar 27 '12 01:03

John Carter


People also ask

How do I delete a record in SQLAlchemy?

Delete multiple rows in SQLAlchemyGet the books table from the Metadata object initialized while connecting to the database. Pass the delete query to the execute() function and get all the results using fetchall() function. Use a for loop to iterate through the results.

How do I delete a record in flask SQLAlchemy?

To delete a record by id in Python Flask-SQLAlchemy, we can call the session delete method. to call session. delete to mark obj1 and obj2 to be deleted. And then we call session.

Should I use SQLAlchemy core or ORM?

If you want to view your data in a more schema-centric view (as used in SQL), use Core. If you have data for which business objects are not needed, use Core. If you view your data as business objects, use ORM. If you are building a quick prototype, use ORM.


2 Answers

When you call delete() from a query object, SQLAlchemy performs a bulk deletion. And you need to choose a strategy for the removal of matched objects from the session. See the documentation here.

If you do not choose a strategy for the removal of matched objects from the session, then SQLAlchemy will try to evaluate the query’s criteria in Python straight on the objects in the session. If evaluation of the criteria isn’t implemented, an error is raised.

This is what is happening with your deletion.

If you only want to delete the records and do not care about the records in the session after the deletion, you can choose the strategy that ignores the session synchronization:

address_table = Table('address', metadata, autoload=True) addresses = session.query(address_table).filter(address_table.c.retired == 1) addresses.delete(synchronize_session=False) 
like image 29
Carlo Pires Avatar answered Sep 20 '22 16:09

Carlo Pires


Looking through some code where I did something similar, I believe this will do what you want.

d = addresses_table.delete().where(addresses_table.c.retired == 1) d.execute() 

Calling delete() on a table object gives you a sql.expression (if memory serves), that you then execute. I've assumed above that the table is bound to a connection, which means you can just call execute() on it. If not, you can pass the d to execute(d) on a connection.

See docs here.

like image 120
rob Avatar answered Sep 21 '22 16:09

rob