198 votes

Étrange message d'erreur SQLAlchemy : TypeError : l'objet 'dict' ne supporte pas l'indexation

J'utilise un SQL artisanal pour récupérer des données d'une base de données PG, en utilisant SqlAlchemy. J'essaie une requête qui contient l'opérateur SQL like '%' et cela semble lancer SqlAlcjhemy dans 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-il ce qui provoque ce message d'erreur trompeur et comment je peux y remédier ?

[[Modifier]]

Avant que quelqu'un ne pose la question, il n'y a rien de spécial ou de fantaisiste dans les fonctions incluses ci-dessus. Par exemple, la fonction executeSql() invoque simplement conn.execute(sql) et renvoie les résultats. La variable conn est simplement la connexion précédemment établie avec la base de données.

346voto

Lafada Points 6393

Vous devez donner %% pour l'utiliser comme % parce que % en python est utilisé comme formatage de chaîne de caractères, donc lorsque vous écrivez un seul % Il suppose que vous allez remplacer une valeur par celle-ci.

Ainsi, lorsque vous souhaitez placer des % dans une chaîne de caractères avec une requête, toujours en double % .

144voto

SQLAlchemy dispose d'une fonction text() pour envelopper le texte, qui semble échapper correctement le code SQL pour vous.

C'est-à-dire

res = executeSql(sqlalchemy.text(sql))

devrait vous convenir et vous éviter d'avoir à vous échapper manuellement.

13voto

dixit_chandra Points 308

Je ne trouve pas le "executeSql" dans sqlalchemy version 1.2 docs mais la ligne ci-dessous a fonctionné pour moi

engine.execute(sqlalchemy.text(sql_query))

4voto

Tupteq Points 755

J'ai trouvé un autre cas où cette erreur se produit :

c.execute("SELECT * FROM t WHERE a = %s")

En d'autres termes, si vous fournissez le paramètre ( %s ) dans la requête, mais vous oubliez d'ajouter les paramètres de la requête. Dans ce cas, le message d'erreur est très trompeur.

3voto

Brian Cain Points 7150

Il semble que votre problème soit lié à ce bogue .

Dans ce cas, vous devriez utiliser une triple échappée comme solution de rechange.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X