ORM이란?
ORM은 Object-Relation Mapping의 약자로 객체(Object)와 관계형 데이터베이스(Relational Database)를 매핑(Mapping)해주는 것을 말한다. 직접 SQL문을 작성하여 데이터베이스를 핸들링 하지 않고 Class로 정의된 객체간의 관계를 기반으로 SQL문을 자동으로 생성하여 데이터베이스를 핸들링할 수 있게 해준다. django의 경우, 프로젝트 폴더 내에 models.py
파일이 ORM과 관련된 파일이다. 이 파일에 클래스를 작성함으로써 관계형 데이터베이스를 설계할 수 있다.
ORM의 장단점
Pros
- 객체지향적인 코드로 인해 직관적인 코드 작성이 가능하다
- SQL이 아닌 클래스의 메소드로 DB를 핸들링하므로 개발자가 객체 모델만 이용하여 로직을 구현하는 일에 집중할 수 있다.
- 선언문, 할당, 종료같은 부수적인 코드가 없거나 줄어든다.
- 재사용 및 유지보수의 편리성이 증가한다.
- ORM은 독립적으로 작성되어있기 때문에 해당 객체들을 재활용할 수 있다.
- ERD를 보는 것에 대한 의존도를 낮출 수 있다.
- DBMS에 대한 종속성이 줄어든다
- 대부분의 ORM솔루션은 DB에 종속적이지 않다.
Cons
- 모든 것을 ORM만으로 구현하기는 어렵다.
- 프로젝트가 복잡하면 구현 난이도가 상승한다.
- 대용량의 데이터를 처리할 때는 SQL쿼리를 직접 튜닝해서 사용하는 경우가 있다.
- 잘못 구현되면 속도 저하, 일관성 문제가 발생할 수 있다.
- 프로시저가 많은 시스템에선 ORM의 객체지향적인 장점을 활용하기 어렵다.
- 프로시저는 SQL로 만들어져 있는 대형 쿼리인데 이것을 일일이 다시 객체로 바꾸는 작업 자체가 생산성이 좋지 못하다.
SQL문을 직접 작성하지 않고도 RDB를 다룰 수 있게 해주는 기술이기 때문에 자칫 오해할 수 있지만, ORM은 개발자를 RDB로부터 분리시키기 위한 기술이 아니라 오히려 개발자에게 높은 RDB 지식을 요구한다는 점을 잊지 말아야 한다. 클래스 구조를 설계할 때에도 DB의 스키마를 고려해야하기 때문이다.
Django에서의 ORM
django프로젝트 앱 안에 있는 models.py
에 다음과 같이 클래스를 작성한다.
models.py
from django.db import models
class Owner(models.Model):
name = models.CharField(default='', max_length=45, null=True)
email = models.CharField(default='', max_length=300, null=True)
age = models.IntegerField(default=0, null=True)
class Meta:
db_table = 'owners'
class Dog(models.Model):
owner = models.ForeignKey(Owner, on_delete=models.CASCADE)
name = models.CharField(default='', max_length=45, null=True)
age = models.IntegerField(default=0, null=True)
class Meta:
db_table = 'dogs'
Owner와 Dog이라는 클래스는 RDB에서 각각의 테이블로 생성된다. 테이블의 이름은 Meta 클래스의 db_table에서 정해준 이름으로 생성된다. 앱에 대한 models.py
작성이 끝나면 makemigration
을 통해 migrations파일을 생성한다.
migrations 파일
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Owner',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(default='', max_length=45, null=True)),
('email', models.CharField(default='', max_length=300, null=True)),
('age', models.IntegerField(default=0, null=True)),
],
options={
'db_table': 'owners',
},
),
migrations.CreateModel(
name='Dog',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(default='', max_length=45, null=True)),
('age', models.IntegerField(default=0, null=True)),
('owner_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='members.owner')),
],
options={
'db_table': 'dogs',
},
),
]
migrate를 실행하면 위 파일의 내용을 기반으로 RDB에 테이블이 생성된다. migrate을 실행하면 django ORM이 migrations파일의 내용을 실제 RDB에서 수행되는 SQL쿼리문으로 변환하여 RDB에 테이블이 생성된다. 이 때 실행되는 쿼리문은 sqlmigrate
명령어를 통해 볼 수 있다.
RDB에서 생성된 테이블을 확인할 수 있다. 👍
References
'TIL' 카테고리의 다른 글
[TIL] #17. self에 대하여 (0) | 2021.04.11 |
---|---|
[Project] Westagram #1 (0) | 2021.04.07 |
[TIL] #15. Django-Introduction (0) | 2021.03.30 |
[TIL] #14. Framework vs Library (0) | 2021.03.28 |
[TIL] #13. __init__.py (0) | 2021.03.23 |