sqlite 데이터베이스를 쿼리 할 때 커서를 만들어야하는 이유는 무엇입니까?


133

나는 파이썬의 sqlite3 모듈 (그리고 그 문제에 대해 일반적으로 SQL)을 완전히 처음 했고, 이것은 나를 완전히 뒤죽박죽으로 만듭니다. cursor대상 에 대한 설명이 풍부하지 않고 (필요한 것) 이상한 것으로 보입니다.

이 코드 스 니펫은 선호하는 방법입니다.

import sqlite3
conn = sqlite3.connect("db.sqlite")
c = conn.cursor()
c.execute('''insert into table "users" values ("Jack Bauer", "555-555-5555")''')
conn.commit()
c.close()

이것은 잘 작동하지만 (겉으로는 무의미한)없이 작동하더라도 그렇지 않습니다 cursor.

import sqlite3
conn = sqlite3.connect("db.sqlite")
conn.execute('''insert into table "users" values ("Jack Bauer", "555-555-5555")''')
conn.commit()

누구나 내가 왜 필요한지 말해 줄 수 있습니까 cursor?
무의미한 오버 헤드처럼 보입니다. 데이터베이스에 액세스하는 스크립트의 모든 메소드에 대해 cursor? 를 작성하고 파기해야합니다 .
connection객체를 사용하지 않습니까?

답변:


60

잘못 적용 된 추상화는 나에게 보인다. db 커서는 데이터 세트 순회를위한 추상화입니다.

에서 주제에 대한 위키 백과 문서 :

컴퓨터 과학 및 기술에서 데이터베이스 커서는 데이터베이스의 레코드를 순회 할 수있는 제어 구조입니다. 커서는 데이터베이스 레코드의 검색, 추가 및 제거와 같은 순회와 관련하여 후속 처리를 용이하게합니다. 순회의 데이터베이스 커서 특성은 커서를 반복자의 프로그래밍 언어 개념과 유사하게 만듭니다.

과:

커서는 DBMS에서 애플리케이션으로 데이터를 페치하는 데 사용될뿐만 아니라 테이블에서 갱신 또는 삭제 될 행을 식별하는 데 사용될 수 있습니다. SQL : 2003 표준은 해당 목적을 위해 위치 지정된 업데이트 및 위치 지정된 삭제 SQL 문을 정의합니다. 이러한 명령문은 술어와 함께 정규 WHERE 절을 사용하지 않습니다. 대신 커서가 행을 식별합니다. FETCH 문을 사용하여 커서를 열고 행에 이미 위치시켜야합니다.

Python sqlite module 에서 문서 를 확인하면 python 모듈 cursorCREATE TABLE명령문 에도 필요하다는 것을 알 수 있으므로 connectionOP가 올바르게 지적한 것처럼 단순한 객체로 충분할 경우에 사용됩니다 . 이러한 추상화는 사람들이 db 커서를 이해하는 것과 다르기 때문에 사용자 측의 혼란 / 좌절입니다. 효율성에 관계없이 개념적 오버 헤드 일뿐입니다. 문서에서 파이썬 모듈 cursor이 SQL 및 데이터베이스의 커서와 약간 다르다는 것이 지적되면 좋을 것입니다.


7
"전통적인"db 커서와 파이썬에서 db에 사용 된 커서 사이의 (혼음에) 매우 혼란스러운 차이를 인정하여 +1
Paul Draper

3
실제로, cursor를 사용하지 않고도 테이블을 명확하게 작성할 수 있습니다 .
Sroo Stroobandt

38

결과를 가져 오려면 커서 객체가 필요합니다. 귀하의 예제는 그것이 기 때문에 작동하므로 INSERT행을 다시 가져 오려고 하지 않지만 sqlite3docs 를 보면 .fetchXXXX연결 객체에 대한 메소드 가 없다는 것을 알 수 있습니다. a는 SELECT커서없이, 당신은 결과 데이터를 얻을 수있는 방법이 없다는 것입니다.

커서 개체를 사용하면 첫 번째 결과를 가져 오기 전에 여러 쿼리를 실행할 수 있으므로 어떤 결과 집합이 어떤 것인지 추적 할 수 있습니다.


5
또한 염두에 가치 유지가 : PEP 249 정의하지 않는 execute연결 개체에, 이것은이다 sqlite3확장.
Cat Plus Plus

4
여전히 SELECT 문과 함께 작동합니다 : pastebin.com/5ZbhfEn7 . 연결 개체에서 .fetchXXXX 메서드를 호출하지 않기 때문에 연결의 .execute () 메서드에서 반환 한 개체에서 .fetchXXXX 메서드를 호출합니다.
잭 바우어

1
예. 그러나 한 가지 방법은 데이터베이스를 쿼리하는 데 불필요한 커서로 보이는 것입니다 : p
Jack Bauer

2
명시 적으로 커서를 사용하는 것은 좋은 습관 입니다. 자동 커밋 되지 않은 곳에서 향후 프로젝트가 진행될 수 있기 때문입니다 .
Amber

1
그럴 수 있지. 정보 주셔서 감사합니다 :)
Jack Bauer

36

공식에 따라 문서 connection.execute() A는 비표준 바로 가기 중간 커서 객체를 생성합니다 :

Connection.execute
이것은 비표준 단축키로서 cursor () 메서드를 호출하여 커서 객체를 만들고 지정된 매개 변수를 사용하여 커서의 execute () 메서드를 호출 한 다음 커서를 반환합니다.


19

12.6.8. sqlite3를 사용하여 효율적으로 만민을

12.6.8.1. 바로 가기 방법 사용

은 Using 비표준를 execute() , executemany()executescript()연결 개체의 방법은 당신의 코드를 작성할 수 있습니다 더 간결을 당신이 (자주 만들 필요가 없습니다 LY 때문에 불필요한을 커서가 명시 적으로 객체). 대신 Cursor 객체는 암시 적으로 만들어지며 이러한 바로 가기 메서드는 커서 객체를 반환합니다. 이런 식으로 연결 개체에서 단일 호출 만 사용하여 SELECT 문을 실행하고 직접 반복 할 수 있습니다.

( sqlite3 문서 ; 강조 광산.)

왜 연결 개체를 사용하지 않습니까?

연결 객체의 메소드는 비표준 이기 때문에 파이썬 데이터베이스 API 사양 v2.0 (PEP 249)의 일부가 아닙니다 .

Cursor 객체의 표준 메서드를 사용하는 한, 위의 사양을 따르는 다른 데이터베이스 구현으로 전환하면 코드를 완전히 이식 할 수 있습니다. 아마도 import회선 을 변경하기 만하면됩니다.

그러나 당신 connection.execute이 그것을 사용하면 전환이 그렇게 간단하지 않을 가능성이 있습니다. 이것이 cursor.execute대신 사용하려는 주된 이유 입니다.

그러나 전환하지 않을 것이 확실하다면, connection.execute바로 가기를 사용하고 "효율적" 이라고해도 괜찮습니다 .


1

데이터베이스에 대한 동일한 연결을 통해 여러 개의 개별 작업 환경을 가질 수 있습니다.

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