이상한 SQLAlchemy 오류 메시지 : TypeError : 'dict'개체가 인덱싱을 지원하지 않습니다


145

SqlAlchemy를 사용하여 손으로 만들어진 SQL을 사용하여 PG 데이터베이스에서 데이터를 가져옵니다. 연산자 '%'와 같은 SQL이 포함 된 쿼리를 시도 중이며 루프를 통해 SqlAlcjhemy를 던지는 것 같습니다.

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

이 잘못된 오류 메시지의 원인과 해결 방법을 아는 사람이 있습니까?

[[편집하다]]

누군가가 묻기 전에, 위에 포함 된 기능들에 대해 특별하거나 공상적인 것은 없습니다. 예를 들어, executeSql () 함수는 단순히 conn.execute (sql)를 호출하고 결과를 리턴합니다. conn 변수는 단순히 이전에 설정된 데이터베이스 연결입니다.


코드를 게시 할 수 executeSql(...)있습니까? 또한, 당신은 정말해야합니까 RETURNING *SELECT문?
van

@van 나는 그 것을 놓쳤다. 문제를 일으키는 SQL에는 'RETURNING *'가 없습니다. 질문을 바로 잡겠습니다.
Homunculus Reticulli

1
이 답변이 [ stackoverflow.com/questions/3944276/… 도움이 되었습니까?
van

2
@van : 감사합니다!. 그렇습니다. '%'대신 '\ %%'을 (를) 사용해야했습니다. 이제 명령문이 올바르게 실행됩니다.
Homunculus Reticulli

3
큰. 완전성을 위해 당신을 위해 일한 짧은 답변을 게시하십시오.
van

답변:


227

당신은 줄 필요 %%로 사용 %하기 때문에 %파이썬 당신이 하나 쓸 때 너무 서식 문자열로 사용하는 것입니다 %그것의이 일부 값을 대체하려고하는 가정이.

따라서 %쿼리를 통해 문자열에 단일을 배치하려면 항상 double을 배치하십시오 %.


27
그들이 오류 메시지를 업데이트하기를 원합니다. 매번이 페이지에 착륙하여 답변을드립니다
oshi2016

86

SQLAlchemy에는 text()SQL을 올바르게 이스케이프 처리하는 것으로 보이는 텍스트 줄 바꿈 기능이 있습니다.

res = executeSql(sqlalchemy.text(sql))

당신을 위해 일하고 수동 탈출을하지 않아도됩니다.


13
선택한 답변이어야합니다. 내 경우에는 문제가 해결되었습니다.
Gani Simsek

1
이것은 주석을 피하지 않지만 환상적인 해결책입니다.
ClimbsRocks

그것은 나를 위해 일한 두 번 %로 우리의 모든 쿼리를 변경하는 대신 구현하기 쉬웠다
필립 Oger 보낸



2

이 오류가 표시되면 하나 더 사례를 발견했습니다.

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

즉, %s쿼리에 매개 변수 ( ) 를 제공 하지만 쿼리 매개 변수를 추가하는 것을 잊어 버린 경우. 이 경우 오류 메시지가 매우 잘못되었습니다.


1

한 번 더 메모- %주석에서 문자를 이스케이프하거나 삭제해야합니다 . 불행히도, sqlalchemy.text(query_string)주석에서 백분율 기호를 피하십시오.


1

%문자 를 이스케이프 하거나 사용 하지 않으려는 경우 문제를 해결하는 또 다른 방법은 sqlalchemy.text()정규식을 사용하는 것입니다.

대신에:

select id from ref_geog where short_name LIKE '%opt'

시도 (대소 문자 구분)

select id from ref_geog where short_name ~ 'opt$' 

또는 (대소 문자를 구분하지 않음) :

select id from ref_geog where short_name ~* 'opt$'

패턴 일치LIKE 에 대한 문서 에서 정규식과 정규식이 모두 다루어 집니다 .

참고 :

LIKE 패턴과 달리 정규식이 문자열의 시작 또는 끝에 명시 적으로 고정되어 있지 않으면 정규식은 문자열 내 어디에서나 일치 할 수 있습니다.

앵커 $의 경우 문자열 끝 (또는 ^시작)에 어설 션 을 사용할 수 있습니다 .


0

SQL로 전달 될 매개 변수가 DICT 형식으로 선언되어 LIST 또는 TUPPLE 형식으로 SQL에서 조작되는 경우에도 발생할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.