Quelle est la cause la plus probable de l'erreur suivante et comment puis-je la corriger? Je ne comprends pas pourquoi SQLAlchemy générerait une requête avec une expression manquante! Et le code fonctionne sur SQLite mais échoue sur Oracle. Quel est le problème avec la requête SQL ci-dessous?
Ce code Python fonctionne sur SQLite mais échoue sur Oracle 11g:
"Internal Server Error: (cx.Oracle.DatabaseError) ORA-00936: missing expression"
Les résultats ci-dessus donnent la requête suivante: p >
SELECT EXISTS ( SELECT 1 FROM locomotion JOIN virion ON locomotion.id = virion.id JOIN locomotion_link ON locomotion_link.parent_id = 16 WHERE locomotion_link.child_id = virion.id AND locomotion_link.child_id != 16 ) AS anon_1 FROM DUAL
Cela fonctionne sur SQLite mais échoue sur Oracle 11g avec
q = (session.query(locomotion_class).join(LocomotionLink, LocomotionLink.parent_id == self.id).filter(LocomotionLink.child_id == locomotion_class.id, LocomotionLink.child_id != self.id)) # locomotion_class is any of the subclasses of Locomotion (in this case Virion) return session.query(q.exists()).scalar()
Lorsque j'essaye d'exécuter l'expression générée dans sqlplus, un astérisque s'affiche moins de 6 ans dans "parent_id = 16" (c'est-à-dire directement avant WHERE) mais je ne vois rien qui manque.
3 Réponses :
Eh bien, oui - select existe
n'est pas valide dans Oracle car il doit être utilisé dans le cadre de la clause where
, telle que
SELECT 1 AS anon_1 FROM locomotion JOIN virion ON locomotion.id = virion.id JOIN locomotion_link ON locomotion_link.parent_id = 16 WHERE locomotion_link.child_id = virion.id AND locomotion_link.child_id != 16
D'un autre côté, la sous-requête que vous avez écrite suggère qu'il pourrait s'agir d'une colonne retour de requête, par exemple
SELECT (SELECT 1 FROM locomotion JOIN virion ON locomotion.id = virion.id JOIN locomotion_link ON locomotion_link.parent_id = 16 WHERE locomotion_link.child_id = virion.id AND locomotion_link.child_id != 16) AS anon_1 FROM DUAL
mais c'est un peu stupide car cela peut être juste
SELECT ... FROM ... WHERE EXISTS (SELECT 1 FROM locomotion JOIN virion ON locomotion.id = virion.id JOIN locomotion_link ON locomotion_link.parent_id = 16 WHERE locomotion_link.child_id = virion.id AND locomotion_link.child_id != 16)
Que devrais tu faire? Je n'ai aucune idée. Cela dépend de ce que vous voulez faire.
Merci beaucoup, votre réponse a été très utile!
La syntaxe
SELECT 1 FROM DUAL WHERE EXISTS ( SELECT 1 FROM locomotion JOIN virion ON locomotion.id = virion.id JOIN locomotion_link ON locomotion_link.parent_id = 16 WHERE locomotion_link.child_id = virion.id AND locomotion_link.child_id != 16 )
ne convient pas à Oracle, mais préfère utiliser:
SELECT EXISTS ( <a subquery> ) AS anon_1 FROM DUAL
Merci de votre aide!
(a publié une réponse au nom de l'auteur de la question, pour la déplacer de la question vers l'espace de réponse).
Sur la base du commentaire et des réponses ci-dessous, j'ai implémenté le correctif suivant:
return session.query(literal(True)).filter(q.exists()).scalar()
Je pense que vous devriez lire les notes sur "certaines bases de données" dans docs.sqlalchemy.org/en/13/orm/...
Merci, votre commentaire a été utile!