web-dev-qa-db-fra.com

Comment supprimer des lignes d'une table à l'aide d'une requête SQLAlchemy sans ORM?

J'écris un script de maintenance rapide et sale pour supprimer certaines lignes et j'aimerais éviter d'avoir à apporter mes classes/mappages ORM du projet principal. J'ai une requête qui ressemble à:

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

D'après tout ce que j'ai lu, si j'utilisais l'ORM (pas "simplement" des tables) et que je passais quelque chose comme:

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

Je pourrais ajouter une .delete() à la requête, mais lorsque j'essaie de le faire en utilisant uniquement des tables, je reçois une plainte:

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

Ce qui est logique car c'est une table, pas une classe. Je suis assez vert en ce qui concerne SQLAlchemy, comment dois-je procéder?

32
John Carter

En parcourant un code où j'ai fait quelque chose de similaire, je pense que cela fera ce que vous voulez.

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

L'appel de delete() sur un objet table vous donne un sql.expression (Si la mémoire est bonne), que vous exécutez ensuite. J'ai supposé ci-dessus que la table est liée à une connexion, ce qui signifie que vous pouvez simplement appeler execute() dessus. Sinon, vous pouvez passer le d à execute(d) sur une connexion.

Voir les documents ici .

38
rob

Lorsque vous appelez delete() à partir d'un objet de requête, SQLAlchemy effectue une suppression en bloc. Et vous devez choisir une stratégie pour la suppression des objets correspondants de la session . Voir la documentation ici .

Si vous ne choisissez pas une stratégie pour la suppression des objets correspondants de la session, SQLAlchemy tentera d'évaluer les critères de la requête dans Python directement sur les objets de la session. Si l'évaluation des critères n'est pas implémentée, une erreur est générée.

C'est ce qui se passe avec votre suppression.

Si vous souhaitez uniquement supprimer les enregistrements et ne vous souciez pas des enregistrements de la session après la suppression, vous pouvez choisir la stratégie qui ignore la synchronisation de la session:

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