2012-03-27 21 views
21

Estoy escribiendo un script de mantenimiento rápido y sucio para eliminar algunas filas y me gustaría evitar tener que traer mis clases ORM/mapeos desde el proyecto principal. Tengo una consulta que tiene un aspecto similar a:Cómo eliminar filas de una tabla con una consulta SQLAlchemy sin ORM?

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

De acuerdo con todo lo que he leído, si yo estaba usando el ORM (no 'sólo' tablas) y aprobada en algo así como:

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

podría añadir un .delete() a la consulta, pero cuando trato de hacer esto usando sólo las tablas que conseguir una queja:

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

lo cual tiene sentido ya que es una mesa, no una clase. Estoy bastante verde cuando se trata de SQLAlchemy, ¿cómo debería hacerlo?

Respuesta

28

Mirando a través de algún código donde hice algo similar, creo que esto hará lo que quiera.

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

Llamar a delete() en un objeto de tabla le da una expresión sql.expression (si la memoria se sirve), que luego ejecuta. He supuesto anteriormente que la tabla está vinculada a una conexión, lo que significa que simplemente puede llamar al execute(). Si no, puede pasar el d al execute(d) en una conexión.

Consulte los documentos here.

+0

Gracias. Veo dónde me equivoqué. Una combinación de un viejo tutorial y documentación desactualizada. –

20

Cuando llama al delete() desde un objeto de consulta, SQLAlchemy realiza una eliminación masiva . Y debe elegir una estrategia para la eliminación de objetos coincidentes de la sesión. Consulte la documentación here.

Si no elige una estrategia para eliminar objetos coincidentes de la sesión, entonces SQLAlchemy intentará evaluar los criterios de la consulta en Python directamente en los objetos de la sesión. Si no se implementa la evaluación de los criterios, se genera un error.

Esto es lo que está sucediendo con su eliminación.

Si sólo desea eliminar los registros y no se preocupan por los registros de la sesión después de la eliminación, se puede elegir la estrategia que ignora la sincronización de sesión:

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

Falso: no sincronice la sesión. Esta opción es la más eficiente y confiable una vez que la sesión ha expirado, lo que normalmente ocurre después de un commit(), o explícitamente usando expire_all(). Antes de la caducidad, los objetos pueden permanecer en la sesión que de hecho se eliminaron, lo que puede generar resultados confusos si se accede a ellos a través de get() o colecciones ya cargadas. https://kite.com/docs/python;sqlalchemy.orm.query.Query.delete – makkasi

Cuestiones relacionadas