Python은 Java에 비해 표준화된 ORM이나 SQL mapper 기술을 제공하고 있지 않으며, 외부 의존성이 이 역할을 대신하고 있다. Java의 경우, Hibernate와 MyBatis 등의 외부 의존성을 사용하지 않는 건 아니지만 JPA 또는 JDBC라는 표준을 제공하고 있어서 어느 정도 일관된 인터페이스를 제공하고 있으므로 외부 의존성의 교체가 나름 용이한 편이다. 그러나 Python은 표준화된 DB 인터페이스가 없어서 상당히 불편하며, 매번 새로운 라이브러리에 대해 학습해야 하고, 기존 코드를 변경해야 하는 부담이 발생한다.
크게 ORM을 사용하는 방법과 DB connectivity(JDBC, ODBC 수준의 연결성을 의미함)를 사용하는 방법이 있다.
전자의 경우, SQLAlchemy가 단연 압도적인 비중을 차지하고 있으며, Tortoise ORM도 나름 쓸만하지만 막상 써보면 DBMS 타입에 따라 호환성 문제가 존재한다. Django ORM, Peewee, Pony ORM도 있다고 하는데 그냥 고민하지 말고 SQLAlchemy를 사용하자.
DBMS 타입에 따라 상호 호환되지 않는 인터페이스를 제공한다.
pip install mysqlclient
import MySQLdb
만약 두 가지 DBMS에 동시에 접근하는 기능이 필요하다면 두 개의 별도 라이브러리를 도입해서 사용해야 한다. 전혀 다른 스타일의 코드가 두 벌이 필요하다. DBMS가 바뀌면 라이브러리도 바뀌고 기존 코드도 바뀐다. 당연히 개발 생산성이 좋을 리가 없다.
연결을 맺은 다음에, 그 연결 객체를 멀티 프로세스에 공유해서 사용하는 것은 문제가 생길 수 있으므로 연결 객체를 공유하는 대신에 연결 풀(connection pool)을 사용하는 게 바람직하다.
://
(필수)@
:
/
?
Python의 기본 라이브러리인 sqlite3를 사용하는 경우에는 좀 더 생략해서 다음과 같이 사용한다.
ORM을 사용하는 경우에는 sqlite://로 시작하는 URL을 사용한다.
from sqlalchemy import create_engine
engine = create_engine('sqlite:///example.db')
from sqlalchemy import create_engine
engine = create_engine("postgresql://myusername:mypassword@localhost:5432/mydatabase")
import pg8000
create_engine("postgresql+pg8000://myusername:mypassword@localhost:5432/mydatabase")
psycopg2가 기본 라이브러리이다.
from sqlalchemy import create_engine
engine = create_engine("mysql://myusername:mypassword@localhost:3306/mydatabase")
import pymysql
engine = create_engine("mysql+pymysql://myusername:mypassword@localhost:3306/mydatabase")
import mysql.connector
engine = create_engine("mysql+mysqlconnector://myusername:mypassword@localhost:3306/mydatabase")
MySQLdb이 기본 라이브러리이다.