J'utilise SQL à la main pour récupérer les données d'une base de données PG, à l'aide de SqlAlchemy. J'essaye une requête qui contient le SQL comme l'opérateur '%' et qui semble lancer SqlAlcjhemy à travers une boucle:
sql = """
SELECT DISTINCT u.name from user u
INNER JOIN city c ON u.city_id = c.id
WHERE c.designation=upper('fantasy')
AND c.id IN (select id from ref_geog where short_name LIKE '%opt')
"""
# The last line in the above statement throws the error mentioned in the title.
# However if the last line is change to:
# AND c.id IN (select id from ref_geog where short_name = 'helloopt')
# the script runs correctly.
#
# I also tried double escaping the '%' i.e. using '%%' instead - that generated the same error as previously.
connectDb()
res = executeSql(sql)
print res
closeDbConnection()
Quelqu'un sait ce qui cause ce message d'erreur trompeur et comment le corriger?
[[Modifier]]
Avant que quiconque ne pose la question, les fonctions décrites ci-dessus n’ont rien de spécial ou d’impressionnant. Par exemple, la fonction executeSql () appelle simplement conn.execute (sql) et renvoie les résultats. La variable conn est simplement la connexion précédemment établie à la base de données.
Vous devez donner %%
pour l'utiliser en tant que %
car %
en python est utilisé pour le formatage de chaîne. Ainsi, lorsque vous écrivez un %
, cela suppose que vous allez remplacer une valeur par ceci.
Ainsi, lorsque vous souhaitez placer un seul %
dans une chaîne avec une requête, placez toujours le double %
.
SQLAlchemy a une fonction text()
pour le retour à la ligne qui semble échapper correctement à la requête SQL.
C'est à dire.
res = executeSql(sqlalchemy.text(sql))
devrait travailler pour vous et vous éviter de faire l'échappement manuel.
Il semble que votre problème puisse être lié à ce bogue .
Dans ce cas, vous devriez échapper trois fois à une solution de contournement.
Je ne trouve pas "executeSql" dans sqlalchemy version 1.2 docs , mais la ligne ci-dessous a fonctionné pour moi
engine.execute(sqlalchemy.text(sql_query))
Encore une note - vous devez également échapper (ou supprimer) les caractères %
dans les commentaires. Malheureusement, sqlalchemy.text(query_string)
n'échappe pas aux signes de pourcentage dans les commentaires.
J'ai trouvé un cas de plus lorsque cette erreur apparaît:
c.execute("SELECT * FROM t WHERE a = %s")
En d'autres termes, si vous fournissez le paramètre (%s
) dans la requête, mais que vous oubliez d'ajouter des paramètres de requête. Dans ce cas, le message d'erreur est très trompeur.
Une autre façon de résoudre votre problème, si vous ne voulez pas échapper aux caractères %
ou utiliser sqlalchemy.text()
, consiste à utiliser une expression régulière.
Au lieu de:
select id from ref_geog where short_name LIKE '%opt'
Essayez (pour la correspondance sensible à la casse):
select id from ref_geog where short_name ~ 'opt$'
ou (pour la casse):
select id from ref_geog where short_name ~* 'opt$'
LIKE
et regex sont tous deux couverts par documentation sur les correspondances de motifs .
Notez que:
Contrairement aux modèles LIKE, une expression régulière peut correspondre n'importe où dans une chaîne, à moins que l'expression régulière soit explicitement ancrée au début ou à la fin de la chaîne.
Pour une ancre, vous pouvez utiliser l'assertion $
pour la fin de chaîne (ou ^
pour le début).
Cela peut également résulter du cas où les paramètres à transmettre au SQL sont déclarés dans le formate DICT et sont manipulés dans le SQL sous la forme de LIST ou TUPPLE.