[SQLAlchemy] Uppercase vs Camelcase Type

Jaehyeong Kwon·2023년 3월 16일
0

SQLAlchemy를 사용하다가 Integer 타입과 INTEGER 타입이 있는 것을 발견하게 되었습니다. 이 두개의 차이는 뭐가 있을 까 검색하다 흥미로운 글을 찾게 되어 정리하게 되었습니다.

우선 자주 사용하는 Column 클래스의 생성자에 sqlalchemy.types 모듈 하위에 구현되어 있는, 타입을 나타내는 클래스를 넘겨 컬럼 타입의 객체들로 컬럼을 명시합니다. 타입 정보를 생성자에 전달할 때, 클래스 자체를 넘겨도 되고 클래스의 인스턴스를 넘겨도 됩니다. 즉 Column(Integer)Column(Integer())가 동일합니다. 자주 사용되는 타입의 sqlalchemy의 type 클래스, SQL DDL에서의 type, Python의 built-in type 간 매핑은 아래와 같습니다.

  • sqlalchemy.types.BigInteger - BIGINT - int
  • sqlalchemy.types.SmallInteger - SMALLINT - int
  • sqlalchemy.types.Integer - INT - int
  • sqlalchemy.types.Boolean - BOOLEAN or SMALLINT or TINYINT - bool
  • sqlalchemy.types.DateTime - TIME or TIMESTAMP - datetime.datetime
  • sqlalchemy.types.Float - FLOAT or REAL - float
  • sqlalchemy.types.PickleType - BLOB or TINYBLOB or MEDIUMBLOB or LONGBLOG - pickle로 직렬화 가능한 모든 객체
  • sqlalchemy.types.String - CHAR or VARCHAR or TEXT - str
  • sqlalchemy.types.Text - TEXT - str

BigInteger와 BIGINT, Boolean과 BOOLEAN, Text와 TEXT

SQLAlchemy로 모델을 정의하다보면, uppercase된 알파벳으로만 정의된 타입을 확인할 수 있습니다. SQLAlchemy 문서에서는 BingInteger, Boolean, Text 등을 Generic Type이라 부르고, BIGINT, BOOLEAN, TEXT 등을 SQL Standard and Multiple Vendor Type 이라고 부릅니다.

Generic Type

BigInteger, Boolean, Text, DateTime, Float, Integer, ...

Python 타입의 데이터를 읽고, 쓰고, 저장할 수 있는 column을 명시합니다. SQLAlchemy는 Generic Type의 컬럼에 대해 테이블 생성 DDL문에 대해 대상 데이터베이스에서 사용할 수 있는 최상의 타입을 알아서 선택합니다. VARCHAR로 정의해뒀는데 데이터베이스가 VARCHAR를 지원하지 않는다면, 그를 대체할 수 있는 타입으로 변경하여 DDL을 작성해줍니다. 한 마디로 요약하자면 어떤 데이터베이스를 사용할지 정해두지 않았다면 Generic Type으로 작성하고 데이터베이스를 연결해도 정상적으로 사용이 가능함을 의미합니다.

SQL Standard and Multiple Vendor Type

BIGINT, BOOLEAN, TEXT, BLOB, CHAR, ...

SQLAlchemy에서 여기에 속하는 타입의 컬럼을 통해 테이블을 생성할때는, 데이터베이스 엔진에 상관없이 컬럼의 타입을 항상 동일하게 만들어낸다. SQLAlchemy가 원하는 타입으로 정확한 DDL을 작성하도록 만들때 유용할 수 있으나, Generic type과 달리 이들은 모든 데이터베이스에서 잘 작동한다는 보장은 없습니다. 만약 데이터베이스가 VARCHAR를 지원하지않는데 VARCHAR를 사용한다면 테이블 생성에 실패합니다.

Vendor-Specific Type

mysql.BIGINT, mysql.BINARY, postgresql.REAL

'벤더 별로 명시되어 있는 타입'을 의미하는데, 여기서 벤더는 MySQL, PostgreSQL 등을 떠올리면 됩니다. sqlalchemy.dialects 패키지 하위에 데이터베이스 별로 패키지가 존재하고, 여기에 명시되어 있는 타입을 사용하는 방식입니다.

from sqlalchmemy import declarative_base
from sqlalchemy.dialects import mysql

Base = declarative_base()


class Students(Base):
	__tablename__ = 'students'
    
    id = Column(mysql.INTEGER, primary_key=True)
    name = Column(mysql.VARCHAR)
profile
나무와 같이 성장하는 사람

0개의 댓글