SQLAlchemy로 데이터베이스 연결하기
SQLite와 PostgreSQL용 SQLAlchemy 엔진을 만들고 pd.read_sql에 전달해 테이블을 DataFrame으로 불러옵니다.
SQLAlchemy로 데이터베이스 연결하기은(는) CoddyKit의 무료 Pandas & NumPy Academy 강의입니다. 이것은 4개 중 1번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Pandas & NumPy Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Pandas & NumPy Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
Pandas를 데이터베이스에 연결하는 이유
운영 환경의 데이터 대부분은 CSV 파일이 아니라 PostgreSQL, MySQL, SQLite 또는 SQL Server와 같은 관계형 데이터베이스에 저장됩니다. Pandas를 데이터베이스에 직접 연결하면 먼저 CSV로 내보내지 않고도 데이터를 DataFrame으로 조회할 수 있고, 정리한 DataFrame을 테이블에 다시 저장할 수 있으며, Python의 분석 기능과 데이터베이스의 인덱싱 및 조인 기능을 결합할 수 있습니다. Pandas와 데이터베이스를 연결하는 다리는 Python의 표준 데이터베이스 추상화 라이브러리인 SQLAlchemy입니다.
SQLAlchemy 설치하기
SQLAlchemy는 Python용 SQL 도구 모음이자 ORM입니다. Pandas와 통합할 때는 ORM이 아닌 Core 계층만 있으면 됩니다. pip install sqlalchemy로 설치합니다. 또한 사용할 데이터베이스에 맞는 드라이버가 필요합니다. PostgreSQL에는 psycopg2, MySQL에는 pymysql, SQLite에는 Python에 내장된 sqlite3를 사용합니다. SQLAlchemy는 추상화 계층으로 작동하므로 연결 문자열만 변경하면 동일한 Pandas 코드를 지원되는 모든 데이터베이스에서 사용할 수 있습니다.
# Install dependencies
# pip install sqlalchemy psycopg2-binary # for PostgreSQL
# pip install sqlalchemy pymysql # for MySQL
# sqlite3 is built into Python
import sqlalchemy as sa
import pandas as pd
print('SQLAlchemy version:', sa.__version__)연결 엔진 만들기
첫 단계는 데이터베이스 유형, 인증 정보, 호스트, 포트, 데이터베이스 이름을 담은 연결 URL을 사용해 SQLAlchemy 엔진을 만드는 것입니다. 엔진은 데이터베이스 연결을 생성하는 공장 역할을 하며, 실제로 필요할 때까지 연결을 열지 않습니다. 엔진을 Pandas의 pd.read_sql() 및 df.to_sql() 함수에 전달합니다. 인증 정보를 코드에 직접 작성하지 말고 환경 변수나 비밀 관리자에서 읽어 오세요.
import sqlalchemy as sa
import os
# SQLite (file-based, no server needed)
sqlite_engine = sa.create_engine('sqlite:///mydata.db')
# PostgreSQL
# pg_url = 'postgresql://user:pass@localhost:5432/mydb'
# pg_engine = sa.create_engine(pg_url)
# From environment variable (safer)
# pg_engine = sa.create_engine(os.environ['DATABASE_URL'])
print(sqlite_engine)
print(type(sqlite_engine))pd.read_sql_table()로 테이블 읽기
pd.read_sql_table('table_name', con=engine)은 데이터베이스 테이블 전체를 DataFrame으로 읽습니다. 데이터베이스 스키마에서 열의 데이터 형식을 자동으로 추론하므로 정수는 정수로, 타임스탬프는 날짜 및 시간 형식으로 유지됩니다. 이는 CSV의 형식 추론보다 정확합니다. columns 인수로 열을 제한할 수도 있고, schema를 사용해 기본값이 아닌 데이터베이스 스키마에서 행을 필터링할 수도 있습니다. 매우 큰 테이블에서는 모든 데이터를 RAM에 불러오므로 주의해야 합니다.
import pandas as pd
import sqlalchemy as sa
engine = sa.create_engine('sqlite:///sales.db')
# Read a full table
df = pd.read_sql_table('orders', con=engine)
print(df.shape)
print(df.dtypes)
print(df.head())pd.read_sql_query()로 조회 실행하기
pd.read_sql_query('SELECT ...', con=engine)은 임의의 SQL SELECT 문을 실행하고 결과를 DataFrame으로 반환합니다. 이는 가장 유연한 방법입니다. Pandas로 불러오기 전에 SQL에서 필터링, 조인, 집계를 수행하여 필요한 행과 열만 읽을 수 있습니다. 조회문은 일반 Python 문자열로 작성합니다. SQL 삽입을 방지하려면 사용자 입력을 조회문에 직접 이어 붙이지 말고 매개변수화된 조회를 사용하세요.
import pandas as pd
import sqlalchemy as sa
engine = sa.create_engine('sqlite:///sales.db')
query = '''
SELECT customer_id, SUM(amount) AS total_spent,
COUNT(*) AS num_orders
FROM orders
WHERE status = 'completed'
GROUP BY customer_id
ORDER BY total_spent DESC
LIMIT 100
'''
top_customers = pd.read_sql_query(query, con=engine)
print(top_customers.head())안전한 매개변수화된 조회
사용자가 제공한 값을 문자열 연결로 SQL 조회문에 넣지 마세요. SQL 삽입 취약점이 발생할 수 있습니다. 대신 매개변수화된 조회를 사용하고, 이름이 지정된 자리 표시자와 함께 매개변수를 사전으로 전달하세요. SQLAlchemy가 이스케이프 처리를 담당합니다. 자리 표시자의 문법은 SQLAlchemy 텍스트 조회에서는 :name이고, psycopg2 방식의 조회에서는 %(name)s입니다. 좋은 습관을 기르려면 내부 스크립트에서도 항상 매개변수화를 사용하세요.
import pandas as pd
import sqlalchemy as sa
engine = sa.create_engine('sqlite:///sales.db')
# Safe: parameterised query
params = {'status': 'completed', 'min_amount': 500.0}
query = sa.text(
'SELECT * FROM orders WHERE status = :status AND amount > :min_amount'
)
with engine.connect() as conn:
df = pd.read_sql_query(query, con=conn, params=params)
print(f'Loaded {len(df)} rows')대규모 조회 결과를 청크로 처리하기
대규모 조회 결과에는 pd.read_sql_query()에서 chunksize를 사용하세요. 그러면 모든 결과를 한 번에 불러오는 대신 DataFrame의 반복자를 받을 수 있습니다. 이는 pd.read_csv(chunksize=...)의 동작과 비슷하지만 데이터베이스에서 행을 묶음 단위로 가져옵니다. 여기에 누적 집계 패턴을 함께 사용하면 RAM을 모두 소진하지 않고도 수백만 행의 조회 결과를 집계할 수 있습니다.
import pandas as pd
import sqlalchemy as sa
engine = sa.create_engine('postgresql://user:pass@host/db')
total = 0.0
count = 0
for chunk in pd.read_sql_query(
'SELECT amount FROM orders',
con=engine,
chunksize=50000
):
total += chunk['amount'].sum()
count += len(chunk)
print(f'Mean amount: {total/count:.2f}')연결 컨텍스트 관리자
데이터베이스 연결은 항상 컨텍스트 관리자(with engine.connect() as conn:) 안에서 열어야 합니다. 그러면 예외가 발생하더라도 연결이 제대로 닫힙니다. 연결을 닫지 않으면 운영 환경에서 연결 풀 고갈이 발생하여 새 조회가 빈 연결을 기다리며 멈출 수 있습니다. SQLAlchemy의 연결 풀은 정해진 수의 연결을 관리하며 컨텍스트 관리자를 사용하면 연결을 자동으로 재활용합니다.
import pandas as pd
import sqlalchemy as sa
engine = sa.create_engine('sqlite:///sales.db')
# Using context manager — connection always closed properly
with engine.connect() as conn:
df = pd.read_sql_query(
'SELECT * FROM products WHERE category = "Electronics"',
con=conn
)
print(f'Products loaded: {len(df)}')
# Connection is automatically returned to the pool here데이터베이스 스키마 확인하기
조회문을 작성하기 전에 어떤 테이블과 열이 존재하는지 알아야 합니다. SQLAlchemy의 Inspector를 사용하면 원시 SQL을 작성하지 않고도 데이터베이스 스키마를 조회할 수 있습니다. inspector.get_table_names()은 모든 테이블을 나열하고, inspector.get_columns('table')은 열 이름과 형식을 반환합니다. 익숙하지 않은 데이터베이스를 다룰 때 유용하며, PRAGMA table_info()나 \d tablename을 직접 실행하는 것보다 깔끔합니다.
import sqlalchemy as sa
engine = sa.create_engine('sqlite:///sales.db')
inspector = sa.inspect(engine)
# List all tables
tables = inspector.get_table_names()
print('Tables:', tables)
# Get columns for the 'orders' table
for col in inspector.get_columns('orders'):
print(f' {col["name"]}: {col["type"]}')엔진 닫기와 권장 사항
오래 실행되는 스크립트나 웹 애플리케이션에서는 작업이 끝났을 때 engine.dispose()을 호출하여 풀의 모든 연결을 닫으세요. 짧게 실행되는 스크립트에서는 Python의 가비지 수집기가 정리를 처리합니다. 데이터 파이프라인에서 데이터베이스 연결을 사용할 때의 권장 사항은 다음과 같습니다. 스크립트 상단에서 엔진을 한 번만 만들고 재사용하며, 연결 풀 기본값(pool_size=5)을 사용하고, pool_pre_ping=True를 활성화하여 조회 사이에 데이터베이스 서버가 다시 시작되면 자동으로 재연결되게 하세요.
import sqlalchemy as sa
# Production-grade engine creation
engine = sa.create_engine(
'postgresql://user:pass@host:5432/mydb',
pool_size=5, # max 5 persistent connections
max_overflow=10, # allow 10 temporary extra connections
pool_pre_ping=True, # verify connection before use
connect_args={'connect_timeout': 10}
)
# ... run all your queries ...
# At the end of the application/script
engine.dispose()
print('Engine disposed')read_sql과 read_csv의 속도 비교
적절한 인덱스가 있는 데이터베이스에 이미 데이터가 있다면, 필터가 적용된 pd.read_sql_query가 CSV로 내보낸 뒤 읽는 것보다 빠른 경우가 많습니다. 데이터베이스 서버가 데이터를 전송하기 전에 필터를 적용하므로 네트워크 전송량과 구문 분석에 드는 비용이 줄어듭니다. 열이 매우 많은 테이블에서는 필요한 열만 선택할 수도 있습니다. 그러나 느린 네트워크를 통해 원격 데이터베이스에서 읽는 작업은 로컬 Parquet 파일을 읽는 것보다 느릴 수 있으므로, 사용 중인 환경에서 두 방법을 항상 프로파일링해 보세요.
import pandas as pd
import sqlalchemy as sa
import time
engine = sa.create_engine('sqlite:///data.db')
# Database read with server-side filter
start = time.time()
df_sql = pd.read_sql_query(
'SELECT * FROM transactions WHERE amount > 100 AND year = 2024',
con=engine
)
print(f'SQL read: {time.time()-start:.3f}s, {len(df_sql):,} rows')빠른 확인
이 단원에서 배운 데이터 분석 개념을 제대로 이해했는지 확인해 보세요.
단원 요약
이 단원에서는 다음을 배웠습니다. sa.create_engine()은 URL 문자열로 재사용 가능한 연결 공장을 만들고, pd.read_sql_query()는 임의의 SQL을 실행하여 DataFrame을 반환합니다. 또한 sa.text() 및 params와 함께 사용하는 매개변수화된 조회는 SQL 삽입 취약점을 방지합니다. 다음으로 Pandas에서 더 복잡한 SQL 조회를 실행하고 SQL과 Python 로직을 결합하는 방법을 알아봅니다.
자주 묻는 질문
“SQLAlchemy로 데이터베이스 연결하기” 강의는 무료인가요?
네 — “SQLAlchemy로 데이터베이스 연결하기” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Pandas & NumPy Academy 강의 전체를 잠금 해제할 수 있습니다. Pandas & NumPy Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
“SQLAlchemy로 데이터베이스 연결하기”에서 뭘 배우나요?
SQLite와 PostgreSQL용 SQLAlchemy 엔진을 만들고 pd.read_sql에 전달해 테이블을 DataFrame으로 불러옵니다. 브라우저에서 직접 실행하는 실습 코드로 Pandas & NumPy Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
Pandas & NumPy Academy을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 Pandas & NumPy Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 1번째 강의입니다.
“SQLAlchemy로 데이터베이스 연결하기” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 Pandas & NumPy Academy 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 Pandas & NumPy Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- SQLAlchemy로 데이터베이스 연결하기
- Pandas에서 SQL 쿼리 실행하기
- DataFrame을 데이터베이스 테이블에 쓰기
- Pandas와 SQL: 알맞은 도구 선택