SQLAlchemy에서 ORM을 사용하기 위해, 스키마를 class로 정의하는 방법이 있다.

sqlalchemy.declarative_base 함수를 통해 Base를 얻고, 이를 상속받는 형태로 모델을 구현한다. 클래스의 내부에는 __tablename__이라는 클래스 필드로 테이블 이름을 명시하며, Column 클래스의 생성자에 sqlalchemy.types 모듈 하위에 구현되어 있는, 타입을 나타내는 클래스를 넘겨 Column 타입의 객체들로 컬럼을 명시한다. 타입 정보를 생성자에 전달할 때, 클래스 자체를 넘겨도 되고 클래스의 인스턴스를 넘겨도 된다. Column(Integer)Column(Integer())가 동일하다는 것이다. sqlalchemy의 타입 클래스, SQL DDL에서의 타입, Python의 빌트인 타입 간 매핑은 다음과 같다. 자주 사용하는 타입 위주로 작성했다.

  • 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 | asdecimal 인자를 True로 설정하면, decimal.Decimal 타입으로 다뤄진다.
  • sqlalchemy.types.PickleType - BLOB or TINYBLOB or MEDIUMBLOB or LONGBLOB - pickle로 직렬화 가능한 모든 객체 | list나 dict를 관리할 때 편리하게 사용할 수 있다.
  • sqlalchemy.types.String - CHAR or VARCHAR or TEXT - str
  • sqlalchemy.types.Text - CLOB or TEXT - str

BigInteger와 BIGINT, Boolean과 BOOLEAN, Text와 TEXT, ...

SQLAlchemy로 모델을 정의하다 보면, uppercase된 알파벳으로만 정의된 타입을 확인할 수 있다. SQLAlchemy 문서에서는 BigInteger, 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의 컬럼에 대해 CREATE TABLE문을 만들어낼 때, 대상 데이터베이스에서 사용할 수 있는 최상의 타입을 알아서 선택한다. VARCHAR로 정의해 뒀는데 데이터베이스가 VARCHAR를 지원하지 않는다면, 그를 대체할 수 있는 타입으로 변경하여 DDL을 작성한다. 대충 써두면, 알아서 테이블을 생성해준다는 의미다. 코드 레벨에서 조금 더 편하다.

SQL Standard and Multiple Vendor Type

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

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

Vendor-Specific Type

mysql.BIGINT, mysql.BINARY, postgresql.REAL, oracle.VARCHAR2, ...

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


'Python 계열 > SQLAlchemy' 카테고리의 다른 글

Query 객체의 WHERE절 작성  (0) 2019.02.12
text()  (0) 2019.02.12
Column.like, Column.ilike, not_, ~expr  (0) 2019.02.12
특정 컬럼만 SELECT  (0) 2019.02.12
aliasing과 함수  (0) 2019.02.12

+ Recent posts