[Python] Python Database API - Python에서는 어떻게 DB와 연결할까?

반응형

오늘은 기초적인 지식을 돌아보겠습니다.

 

우리가 서버를 개발하다 보면 자연스레 등장하는 것이 바로 Database입니다. 사용자가 요청한 데이터를 저장하는 데도 데이터베이스를 사용하고, 그 데이터를 액세스하는 데도 데이터베이스를 사용하는데, 이 데이터베이스는 도대체 무엇일까요?

 

 

 

What is Database ?

데이터베이스, 현대 컴퓨터 프로그래밍(?)을 공부하다보면 자연스레 등장하는 단어입니다. 데이터베이스란, 컴퓨터 시스템에서 전자적으로 저장되고 액세스되는 조직화 된 데이터 모음을 이야기합니다. 한마디로 현실 세계에 존재하는 숫자, 문자 등의 데이터를 전자적으로(메모리, 디스크) 저장하고, 이를 조직화하여 액세스 하는 것이죠.

 

그럼 DBMS는 무엇일까요? DBMS는 Database Management System의 약자로 데이터베이스 관리를 위한 핵심 기능을 포함하여 사용자와 데이터베이스 간에 상호작용하여 데이터를 분석하고 액세스하는 소프트웨어입니다. 데이터베이스에 있는 데이터가 전자적으로 저장되어 있지만 사람이 쉽게 읽을 수 없어, 이를 상호작용 하는 소프트웨어인 것이지요.

 

가령 우리가 데이터베이스에 "Neon K.I.D 블로그 | https://blog.neonkid.xyz" 이렇게 저장했다고 하더라도 컴퓨터는 이를 그대로 저장하여 보관하지 않습니다. 컴퓨터의 원초 계산인 이진수(0000100000) 형태로 저장하는데, 이를 사용자가 해석하거나 읽을 수 없으므로 이를 쉽게 저장하고, 읽을 수 있도록 도와주는 것이 바로 DBMS 입니다.

 

 

 

Python에서 DB와 연결하는 방법

Python에서 데이터베이스를 연결할 수 있는 방법에는 pyODBC를 사용하는 방법이 있습니다. pyODBC는 ODBC를 사용하여 Database를 연결하는 구현체를 제공하는 라이브러리입니다. ODBC에 대해서 잘 모르신다면, 아래의 글을 참고해보세요.

 

 

리눅스에서 Unix ODBC를 사용해보자

안녕하세요. 2018년의 연말이 다가왔습니다. 오늘은 2018년의 마지막 포스트로 우분투에서 Unix ODBC를 설정하는 방법에 대해 알아보도록 하겠습니다. What is ODBC? Unix ODBC를 설치하기 전에, ODBC가 무엇

blog.neonkid.xyz

그러나 ODBC는 운영체제에 맞게 드라이버를 설치해야 하고, 설치로 끝나는 것이 아니라 해당 드라이버의 위치와 ODBC 설정을 해줘야만 비로소 연결을 할 수 있는 복잡한 절차를 거쳐야 합니다.

 

이런 복잡함을 덜어주기 위해 데이터베이스 표준 인터페이스를 제공하는데, Python에서는 이를 DB API라고 합니다. 그런데, API는 뭐죠?

 

 

 

What is API ?

API는 Application Programming Interface의 약자로 응용 프로그램이 운영체제 또는 DBMS 또는 통신 프로토콜과 같은 다른 제어 프로그램과 통신하는 데 사용하는 언어 및 메시지 형식을 말합니다. 

 

가령 우리는 프로그래밍 언어로 Python 뿐만 아니라 C++, Java, Go, Rust 등 다양한 언어가 있고 해당 언어에 맞게 DB와 연결하고 통신 프로토콜을 제어하는 등 그 언어에 맞게 제공되는 형식을 말하는 것이지요. 이러한 API는 실행에 필요한 프로그램 내 함수 호출로 작성하여 구현됩니다.

 

 

 

Python DBAPI 2.0

파이썬에서는 DB와 연결하는 API를 DBAPI(Database API)라 합니다. DBAPI는 현재 2.0까지 고안되어 있고, 이는 2001년 처음 계획 되어(PEP249) 지금까지 사용되고 있습니다.

 

Python에서 데이터베이스와 연결하는 방법은 간단합니다. Application과 DB 사이에 Connector가 존재하며(DB마다 다름) 이 커넥터를 통해 애플리케이션에 DB로 연결을 요청합니다. DB에서 요청을 수락하면, 커서를 이용해 SQL 쿼리를 질의하여 데이터를 가져오거나 저장할 수 있습니다.

 

 

 

Python DBAPI 개념

DB API의 구조는 매우 간단합니다. 기본적으로 Database에서 필요한 연결 객체(DB 연결)와 커서 객체(데이터 액세스 및 영속)로 이루어져 있습니다. 

 

먼저 연결 객체(Connection Objects)에는 아래의 4가지 메서드가 제공됩니다.

 

  1. cursor(factory=Cursor)
    cursor 메서드는 데이터베이스 커넥션으로 생성하며, 연결된 DB로 Cursor 객체를 수행하는 메서드입니다.
    Cursor 객체에는 SQL 질의(Query)를 수행하고 결과를 얻는데 사용하는 객체로 SELECT 쿼리를 수행할 때 사용합니다. (INSERT, UPDATE와 같은 DB 단일 적용 쿼리는 제외)

  2. commit()
    commit은 현재 트랜잭션을 커밋하는 메서드입니다. (커밋에 대해서는 데이터베이스의 트랜잭션에 대해 참고해보세요.) 이 메서드를 호출하지 않으면 데이터베이스에 데이터가 영속되지 않습니다.

  3. rollback()
    rollback은 마지막 commit 메서드 호출 이후의 데이터베이스 변경 사항을 모두 되돌리는 메서드입니다.

  4. close()
    close는 데이터베이스의 연결을 종료하는 메서드입니다. 이 메서드를 호출하기 전, 반드시 commit 메서드를 호출하고 종료하는 걸 권장합니다. 그렇지 않으면 모든 내용이 손실됩니다.

 

커서 객체(Cursor Objects)에도 아래의 4가지 메서드가 제공됩니다. 

 

  1. execute(sql[, parameters])
    SQL 쿼리를 실행하는 메서드로 매개변수에 들어가는 SQL은 JPQL처럼 파라미터화 할 수 있습니다. 

  2. executemany(sql, seq_of_parameters)
    매핑을 통해 여러 파라미터 값이 들어있는 SQL 쿼리를 실행하는 메서드입니다.
    ex) INSERT INTO members (name, city) VALUES = (%s, %s), [('이연', '부산'), ('이밀', '서울')]

  3. fetchone()
    쿼리 결과에서 가장 첫 번째 행을 가져오는 메서드입니다. 만약, 아무런 데이터도 찾을 수 없는 경우 None을 반환합니다.

  4. fetchmany(size=cursor.arraysize)
    모든 쿼리 결과를 가져오는 메서드입니다. 만약 아무런 데이터도 없는 경우 빈 리스트(emtpy list, [])를 반환합니다. 
    매개변수인 size는 한 번 호출당 가져올 최대의 행수를 가져오게 되며 기본값은 cursor에서 DB를 통해 가져온 배열 크기로 지정됩니다.

 

Python에서는 연결 객체와 커서 객체를 잘 사용할 줄만 안다면 어렵지 않게 DB와 연결하고 데이터를 영속, 액세스할 수 있습니다. 

 

그러면 간단한 예제를 다뤄보도록 하겠습니다.

 

 

 

DB API Example

예제로 우리는 PostgreSQL을 사용해보도록 하겠습니다. 만약, PostgreSQL을 설치하지 않았다면 Docker 등을 이용해서 PostgreSQL을 실행해주세요.

$ pip install psycopg2-binary
$ poetry add psycopg2-binary

pip 혹은 poetry 등을 이용하여 PostgreSQL DB Connector 라이브러리를 다운로드 합니다.

 

 

 

connect 메서드를 이용하여 매개변수에 DB 주소를 지정하고 메서드를 호출한 다음 연결 객체를 출력해봅니다.

그리고, 커넥션을 닫음 다음에도 연결 객체를 출력해봅니다.

 

연결에 성공하면 두 객체의 모습이 정상적으로 출력될 것입니다. 연결 객체에는 dsn(DB 연결 정보)과 현재 연결 상태가 연결 중인지, 끊어졌는지를 표시하는 closed로 구성되어 있습니다.

 

 

 

이제 연결이 되었으면 cursor를 띄워서 SQL 문을 실행해볼 수 있는데요. memos라는 테이블을 하나 생성하고 제목(title)과 content(내용) 컬럼을 추가해줍니다. 그리고, 행을 추가한 다음 이를 조회하는 SELECT 쿼리를 날려봤습니다.

 

그러면 fetchone까지 정확하게 되면서 데이터까지 정확하게 로드하고 있는 걸 볼 수 있습니다.

그런데..............................

 

어? 분명히 CREATE TABLE, INSERT 쿼리를 넣어서 테이블을 만들고 행까지 추가했는데, DBMS에 접속해서 보니 나오지 않습니다. 왜 그런 것일까요?

 

바로 커밋(commit)을 하지 않았기 때문입니다. DBAPI에서 DB 연결 후 cursor를 이용해 쿼리를 실행한 다음 commit을 해주지 않고 DB 연결을 종료하는 경우, 과거에 있었던 내용들은 모두 손실됩니다.

(왜냐하면, 커밋을 하기 이전까지는 메모리에만 기록이 남기 때문입니다)

 

 

 

따라서 commit 메서드를 실행해줘야만 데이터베이스에 영구적으로 저장이 되기 때문에 반드시 데이터를 삽입, 수정, 삭제한 경우에는 반드시 commit 메서드를 호출해주도록 합니다.

 

DBMS에 접속해서 확인하면 title, content 컬럼이 있는 memos 테이블이 만들어졌고, 행 데이터까지 정확히 영속된 것을 확인할 수 있습니다.

 

DB API는 파이썬에서 제공하는 표준 API로 다른 데이터베이스에서도 사용할 수 있습니다. 다만 커넥션 하는 프로토콜은 각자 다르기 때문에 다른 라이브러리를 설치해야 하며 대신 같은 인터페이스를 사용하기 때문에 메서드의 사용법이나 커넥션을 생성하고 커서를 사용하는 것 모두 동일하게 적용됩니다.

 

  • MySQL (mysql-connector-python)
  • PostgreSQL (psycopg2-binary)
  • Microsoft SQL Server (pymssql)
  • SQLite3 (sqlite3)

각각의 데이터베아스 벤더별로 DBAPI를 지원하는 라이브러리 이름을 모아두었습니다. pip, poetry 등의 패키지 매니저 명령어를 이용해서 쉽게 설치 해볼 수 있습니다.

 

 

 

마치며...

파이썬 언어는 프로그래밍을 처음 다루시는 분들이 많이 사용하시는 언어 중에 하나입니다. 따라서 해당 언어로 데이터베이스나 메시지 큐 등 다양한 미들웨어 연결 및 기능 구현에 대해 검색들을 많이 하시는데요.

 

이 글에서 중요한 점은 Database의 기초없이는 이 글을 읽지 마시는 것을 권장합니다. 반드시 데이터베이스의 기초적인 지식 (트랜잭션, SQL)을 갖춘 다음 보기를 권장하며 데이터베이스를 다루기 보단 Python 언어에서 어떻게 데이터베이스와 연결하는지에 대해 공부하고자 할 때 보시는 것을 권장합니다.

 

 

반응형

Tistory Comments 2

  • 패린이

    아 저는 왜 기껏 팀플로 FastAPI 백엔드를 맡으며 개발이 다 끝나고서야 작성자님 블로그를 봤을까요..
    이걸 개발 초기에 봤다면 훨씬 생산적이고 효율적으로 코드를 작성할 수 있었을텐데요...
    물론 공식문서가 진리라곤 하지만 이렇게 같은 한글로 논리적으로 정리한 글들을 볼때마다 대단하다고 생각이 드네요..
    우리나라엔 아직 FastAPI도입한 기업도 적고 기술블로그들도 거의 운영되지 않기에 스택오버플로우나 공식문서에만 의존해서 코딩을 진행해왔는데 정보 정말 감사합니다. 프로젝트가 끝나고 개인공부를 할때 중요한 참고가 될 것 같습니다.