2011-12-28 15 views
56

Używam ręcznie spreparowanego SQL do pobierania danych z bazy danych PG, używając SqlAlchemy. Próbuję kwerendy SQL, która zawiera jak operator „%” i że wydaje się rzucać SqlAlcjhemy przez pętlę:Dziwny komunikat o błędzie SQLAlchemy: TypeError: obiekt "dict" nie obsługuje indeksowania

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() 

Każdy wie, co jest przyczyną tego mylący komunikat o błędzie i jak mogę to naprawić?

[[Edit]]

Zanim ktoś pyta, nie ma nic szczególnego lub fantazyjne o funkcjach zawarte powyżej. Na przykład funkcja executeSql() po prostu wywołuje conn.execute (sql) i zwraca wyniki. Zmienna conn jest po prostu wcześniej ustanowionym połączeniem z bazą danych.

+0

Czy możesz wysłać kod 'executeSql (...)'? A także, czy naprawdę masz 'RETURNING *' w wyrażeniu 'SELECT'? – van

+0

@van Tęskniłem za tym. W SQL, który jest przyczyną problemu, nie ma "POWROTU *". Poprawię pytanie. –

+1

czy ta odpowiedź [http://stackoverflow.com/questions/3944276/psycopg2-using-wildcard-causes-typeerror] jest pomocna? – van

Odpowiedz

4

Wygląda na to, że Twój problem może być związany z this bug.

W takim przypadku należy zastosować potrójne wyjście jako obejście.

91

Trzeba dać %% używać go jako % ponieważ % w Pythonie jest zastosowanie jako ciąg formatowania więc kiedy piszesz pojedynczy % jej założyć, że masz zamiar zastąpić jakąś wartość z tym.

Jeśli chcesz umieścić pojedynczy ciąg % w zapytaniu, zawsze umieszczaj podwójne %.

+3

Szkoda, że ​​nie zaktualizują tego komunikatu o błędzie, za każdym razem, gdy go otrzymam, ląduję na tej stronie i odpowiem na – oshi2016

28

SQLAlchemy ma funkcję tekstową do zawijania tekstu, który wydaje się poprawnie wymykać SQL dla ciebie.

tj

res = executeSql(sqlalchemy.text(sql)) 

powinny pracować dla Ciebie i zaoszczędzić od konieczności wykonywania dziwny ucieczkę.

+2

To powinna być wybrana odpowiedź. Rozwiązał problem w moim przypadku. –

+0

Pamiętaj, że to nie umknie uwadze, ale poza tym jest fantastycznym rozwiązaniem. – ClimbsRocks

0

Może to również wynikać z przypadku - w przypadku, gdy parametry przekazywane do SQL są zadeklarowane w formate DICT i są przetwarzane w SQL w postaci LISTY lub TUPPLE.

1

Znalazłem jeszcze jeden przypadek, kiedy ten błąd pojawia się:

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

Innymi słowy, jeśli podasz parametr (%s) w zapytaniu, ale zapomnij dodać params zapytania. W takim przypadku komunikat o błędzie jest bardzo mylący.

0

Jeszcze jedna uwaga - musisz też uciec (lub usunąć) % znaków w komentarzach. Niestety, sqlalchemy.text(query_string) nie uchyla się od znaków procentowych w komentarzach.

Powiązane problemy