programing

DictCursor가 psycopg2에서 작동하지 않는 것 같습니다.

procenter 2021. 1. 17. 12:10
반응형

DictCursor가 psycopg2에서 작동하지 않는 것 같습니다.


전에 psycopg2로 작업 한 적이 없지만 fetchall 또는 fetchone이 목록 대신 사전을 반환하도록 커서 팩토리를 DictCursor로 변경하려고합니다.

작업을 간단하게 만들고이 기능 만 테스트하기 위해 테스트 스크립트를 만들었습니다. 작동해야한다고 생각하는 약간의 코드가 있습니다.

import psycopg2
import psycopg2.extras

conn = psycopg2.connect("dbname=%s user=%s password=%s" % (DATABASE, USERNAME, PASSWORD))

cur = conn.cursor(cursor_factory = psycopg2.extras.DictCursor)
cur.execute("SELECT * from review")

res = cur.fetchall()

print type(res)
print res

res 변수는 항상 목록이며 예상대로 사전이 아닙니다.

내가 구현 한 현재 해결 방법은 사전을 빌드하고이를 통해 fetchall이 반환 한 각 행을 실행하는이 함수를 사용하는 것입니다.

def build_dict(cursor, row):
    x = {}
    for key,col in enumerate(cursor.description):
        x[col[0]] = row[key]
    return d

Python은 버전 2.6.7이고 psycopg2는 버전 2.4.2입니다.


res = cur.fetchall()

s res의 목록을 만듭니다 psycopg2.extras.DictRow.


또는 호출하는 대신 반복 가능한 cur.fetchall사실을 활용할 수 있습니다 cur.

cur.execute("SELECT * from review")
for row in cur:
    print(row['column_name'])

따라서 dict유사한 구문으로 데이터에 액세스 할 수 있습니다 .


RealDictCursor 사용 :

cur = conn.cursor(cursor_factory = psycopg2.extras.RealDictCursor)
cur.execute("SELECT * from review")
res = cur.fetchall()    

이렇게하면 "고급 psycopg2 목록"대신 실제 파이썬 사전으로 행이있는 목록이 제공됩니다.


또 다른 해결책은 Real Dict Cursor가 설명서에 설명 된대로 정수 인덱스를 사용하는 쿼리를 중단하므로 Named Tuple Cursor 를 사용하는 것입니다.

Named Tuple Cursor를 사용하면 다음과 같은 점 구문으로 액세스 할 수 있습니다.

import psycopg2
import psycopg2.extras
cur = conn.cursor(cursor_factory = psycopg2.extras.NamedTupleCursor)
cur.execute("SELECT * from review")
res = cur.fetchone()
res.key1
res.key2

이것은 일을 깔끔하게 유지하고 내가 아는 한 아무것도 깨지 않을 것입니다.


이것은 오래된 질문이지만 여전히 Google에 나와 있으므로 큰 G에서 오는 다른 사람을 위해 여기에 내 코드를 추가 할 것이라고 생각했습니다.

나를 위해, 나는 사전으로 돌아가고 싶은 여러 행을 가지고 있으며 이상적으로는 루프를 사용하거나 데이터베이스의 필드에서 키를 설정하기를 원하지 않습니다.

그래서 dict comprehension syntax나는 다음을 할 수 있습니다.

사전에 테이블 행


pgCursor = Conn.cursor(cursor_factory = psycopg2.extras.RealDictCursor)
pgCursor.execute("SELECT * FROM tablename;",([]))
dictRows = {n['id']: n for n in pgCursor}

기능 및 호출

#NOTE this is using a class object hence the self param
def DBTableToDictByID(self, squery):
    self.Pointer.execute(squery,([]))
    return {n['id']: n for n in self.Pointer}

dictRows = self.DBTableToDictByID("SELECT * FROM tablename;")

이것이 y 루프에서 for x를 사용하는 동안, 내가 말할 수있는 한 파이썬 적입니다 .... 바라건대 이것은 일부 사람들에게 도움이 될 것입니다.


RealDictCursor 기능을 사용하는 것 외에도 답변에서와 같이 모든 열 (선택 후 * 기호 사용)을 요청해야 할 수도 있습니다.

결과의 일부 열에는 WHERE 조건에서 이미 사용 된 알려진 값이 있었기 때문에 관심이 없었습니다. 그러나 SELECT (..., ..., ..., ...) FROM ... WHERE ...변형은 나에게 사전을 제공하지 않았습니다.

친애하는 ! 할리


So to make this work like the mysql version of the Dictionary cursor you will have to wrap it in another function or code. I will go on the forums and suggest this to them for future deployments of their code to return a dictionary when the fetchall() call is used with the Dictionary Cursor. Here is some sample code you can use to fix for it:

cursor.execute(query)
# Python 2.7 and beyond with dictionary comprehension
results = [{key:value for key,value in row.iteritems()} for row in cursor]
# Python 2.6 and before
# results = [dict((key,value) for key,value in row.iteritems()) for row in cursor]

This code makes it the same format as the MySQL version of the dictionary cursor using fetchall(). Not sure why they implemented it differently, but this will help you get the same output of an actual python dictionary rather than a list in the fetchall() case.

ReferenceURL : https://stackoverflow.com/questions/6739355/dictcursor-doesnt-seem-to-work-under-psycopg2

반응형