SQLAlchemy - declarative_base란 무엇일까요?
기본 사용:
declarative_base
함수를 사용하여 새 베이스 클래스를 생성합니다.- 모델 클래스는 이 베이스 클래스를 상속받아야 합니다.
- 각 모델 클래스 속성은 데이터베이스 테이블의 열과 매핑됩니다.
__tablename__
속성은 테이블 이름을 지정합니다.- 데이터 타입 및 제약 조건은 각 속성에 명시됩니다.
- 엔진을 생성하고 데이터베이스에 연결합니다.
- 모델 클래스를 테이블로 생성합니다.
- ORM 기능을 사용하여 데이터를 조작합니다.
예시:
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
engine = create_engine('sqlite:///database.db')
Base = declarative_base()
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
name = Column(String(255))
email = Column(String(255))
# 테이블 생성
Base.metadata.create_all(engine)
# 사용자 추가
user = User(name='John Doe', email='[email protected]')
engine.session.add(user)
engine.session.commit()
# 사용자 검색
user = engine.session.query(User).filter_by(id=1).first()
print(user.name) # 'John Doe' 출력
declarative_base의 장점:
- 간결하고 명확한 코드
- 객체 지향 모델과 데이터베이스 스키마 간의 직관적인 매핑
- 코드 재사용성 향상
- 유지 관리 용이
예제 코드: SQLAlchemy declarative_base 사용법
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String
# 데이터베이스 엔진 생성
engine = create_engine('sqlite:///database.db')
# declarative_base 생성
Base = declarative_base()
class User(Base):
__tablename__ = 'users' # 테이블 이름 지정
id = Column(Integer, primary_key=True) # 기본 키로 사용될 정수 ID
name = Column(String(255), nullable=False) # 이름 (NULL 불가능)
email = Column(String(255), unique=True, nullable=False) # 이메일 (고유하고 NULL 불가능)
# 테이블 생성
Base.metadata.create_all(engine)
# 사용자 추가
user1 = User(name='Alice', email='[email protected]')
user2 = User(name='Bob', email='[email protected]')
# 세션 생성 및 사용자 추가
session = engine.session()
session.add_all([user1, user2])
session.commit()
# 모든 사용자 조회
users = session.query(User).all()
for user in users:
print(f"{user.id}: {user.name} ({user.email})")
# 특정 사용자 조회 (ID 기준)
user = session.query(User).filter_by(id=1).first()
print(f"ID 1 사용자: {user.name} ({user.email})")
# 특정 사용자 조회 (이메일 기준)
user = session.query(User).filter_by(email='[email protected]').first()
print(f"이메일 [email protected] 사용자: {user.name} ({user.email})")
# 사용자 이름 업데이트
user = session.query(User).filter_by(id=2).first()
user.name = 'Bob Smith'
session.commit()
print(f"업데이트된 사용자 이름: {user.name}")
# 사용자 삭제 (ID 기준)
session.delete(session.query(User).filter_by(id=1).first())
session.commit()
print("ID 1 사용자 삭제됨")
# 모든 사용자 삭제
session.query(User).delete()
session.commit()
print("모든 사용자 삭제됨")
설명:
create_engine()
함수를 사용하여 데이터베이스 엔진을 생성합니다.declarative_base()
함수를 사용하여Base
라는 declarative_base 클래스를 생성합니다.User
라는 모델 클래스를 정의하고Base
를 상속받습니다.- 각 속성은 데이터베이스 열과 매핑되며, 데이터 타입과 제약 조건을 명시합니다.
engine.create_all()
메서드를 사용하여 테이블을 생성합니다.User
인스턴스를 생성하고 데이터베이스에 추가합니다.session.query()
메서드를 사용하여 사용자를 조회합니다.filter_by()
메서드를 사용하여 특정 조건에 맞는 사용자를 검색합니다.first()
메서드를 사용하여 쿼리 결과의 첫 번째 레코드를 가져옵니다.update()
메서드를 사용하여 사용자 데이터를 업데이트합니다.delete()
메서드를 사용하여 사용자를 삭제합니다.
주의:
- 이 예제는 기본적인 사용법만 보여줍니다. 실제 응용 프로그램에서는 더 많은 기능이 필요할 수 있습니다.
- 오류 처리 및 예외 처리를 코드에 추가하는 것이 좋습니다.
SQLAlchemy declarative_base 대체 방법
직접 테이블 매핑:
Table
클래스를 사용하여 테이블을 직접 정의합니다.- 각 열을
Column
객체로 정의하고, 데이터 타입 및 제약 조건을 명시합니다. - 모델 클래스에서
__table__
속성을 사용하여 테이블을 연결합니다. - 더 많은 제어력과 유연성을 제공하지만, 코드가 더 복잡해질 수 있습니다.
Mapping Mixins:
- 공통 속성 및 메서드를 정의하는 믹신 클래스를 생성합니다.
- 모델 클래스에서 믹신 클래스를 상속받아 공통 기능을 재사용합니다.
- 코드 재사용성을 높이고, declarative_base의 일부 기능을 제공합니다.
Manual Metaclass:
- 메타클래스를 사용하여 모델 클래스를 동적으로 생성합니다.
- 테이블 이름, 열 이름, 데이터 타입 등을 코드에서 직접 제어합니다.
- 가장 낮은 수준의 제어를 제공하지만, 코드가 매우 복잡해질 수 있습니다.
기타 ORM 도구:
- PonyORM, Ocelot, SqlObject와 같은 다른 ORM 도구를 사용합니다.
- 각 도구마다 장단점이 있으며, 특정 요구 사항에 맞게 선택해야 합니다.
어떤 방법을 선택해야 할까요?
- 간편성과 명확성: declarative_base를 사용하는 것이 가장 좋습니다.
- 더 많은 제어력: 직접 테이블 매핑 또는 Manual Metaclass를 사용합니다.
- 코드 재사용성: Mapping Mixins를 사용합니다.
- 특정 요구 사항: 다른 ORM 도구를 고려합니다.
선택 시 고려 사항:
- 프로젝트의 복잡성
- 개발자의 경험 및 선호도
- 필요한 기능
- 성능 요구 사항
추가 정보:
python sqlalchemy