2012-03-27 19 views
21

Sto scrivendo uno script di manutenzione rapida e sporco per eliminare alcune righe e vorrei evitare di dover portare le mie classi ORM/mapping dal progetto principale. Ho una domanda che sembra simile a:Come eliminare le righe da una tabella utilizzando una query SQLAlchemy senza ORM?

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

Secondo tutto quello che ho letto, se stavo usando l'ORM (non 'solo' tavoli) e passato in qualcosa di simile:

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

potrei aggiungere una .delete() alla query, ma quando provo a farlo usando solo le tabelle ottengo un reclamo:

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_' 

che ha un senso perché è un tavolo, non una classe. Sono abbastanza verde quando si tratta di SQLAlchemy, come dovrei fare questo?

risposta

28

Guardando attraverso un codice in cui ho fatto qualcosa di simile, credo che questo farà quello che vuoi.

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

Chiamare delete() su un oggetto tabella fornisce un'espressione sql (se la memoria serve), che viene quindi eseguita. Ho ipotizzato che la tabella sia vincolata a una connessione, il che significa che puoi semplicemente chiamare execute() su di essa. In caso contrario, è possibile passare la d a execute(d) su una connessione.

Vedere i documenti here.

+0

Grazie. Vedo dove ho sbagliato. Una combinazione di un vecchio tutorial e di una documentazione obsoleta. –

20

Quando si chiama delete() da un oggetto query, SQLAlchemy esegue una cancellazione bulk . E devi scegliere una strategia per la rimozione di oggetti corrispondenti dalla sessione. Vedere la documentazione here.

Se non si sceglie una strategia per la rimozione di oggetti corrispondenti dalla sessione, SQLAlchemy proverà a valutare i criteri della query in Python direttamente sugli oggetti nella sessione. Se la valutazione dei criteri non è implementata, viene generato un errore.

Questo è ciò che sta accadendo con la cancellazione.

Se si desidera solo eliminare i record e non si preoccupano i record della sessione dopo l'eliminazione, è possibile scegliere la strategia che ignora la sincronizzazione sessione:

address_table = Table('address', metadata, autoload=True) 
addresses = session.query(address_table).filter(address_table.c.retired == 1) 
addresses.delete(synchronize_session=False) 
+0

False - non sincronizzare la sessione. Questa opzione è la più efficiente ed è affidabile una volta scaduta la sessione, che in genere si verifica dopo un commit() o che utilizza esplicitamente expire_all(). Prima della scadenza, gli oggetti possono ancora rimanere nella sessione che sono stati effettivamente eliminati, il che può portare a risultati confusi se vi si accede tramite get() o raccolte già caricate. https://kite.com/docs/python;sqlalchemy.orm.query.Query.delete – makkasi

Problemi correlati