4. Odoo 기술 & 개발(Tech, Architecture)/커스텀 모듈 개발 & API

Odoo 개발의 시작: Model 정의와 Field 타입(기본·관계형) 완벽 가이드

wegosolution 2026. 8. 29. 19:05

Odoo(오두) ERP 커스텀 모듈 개발의 핵심은 비즈니스 요구사항에 맞춘 데이터베이스 테이블 및 스키마 구조를 설계하는 것입니다. Odoo 프레임워크는 PostgreSQL 테이블을 직접 DDL로 생성하지 않고, 파이썬 클래스 형태의 모델(Model)과 속성 정의인 필드(Field)를 통해 백엔드 스키마와 ORM을 자동으로 매핑합니다.

1. Odoo 모델(Model)의 개념과 기본 아키텍처

Odoo 모델은 데이터베이스 테이블 및 비즈니스 로직을 캡슐화한 파이썬 클래스 객체입니다. 모든 영속적 비즈니스 모델은 models.Model 클래스를 상속받아 고유한 시스템 식별자 _name을 정의함으로써 생성됩니다.

odoo-models-and-fields-architecture-overview
Odoo models and fields

Python
# school_student.py - 학생 정보를 관리하는 기본 모델 예시
from odoo import models, fields

class Student(models.Model):
    _name = "school.student"
    _description = "Student Information"

    name = fields.Char(string="학생 이름", required=True)
    age = fields.Integer(string="나이")
    active = fields.Boolean(string="재학 여부", default=True)
    enrollment_date = fields.Date(string="등록일")

모델 정의 핵심 속성 분석

  • _name: Odoo 데이터베이스 내에서 해당 모델을 식별하는 고유 테크니컬 네임입니다 (self.env['school.student'] 형태로 ORM에서 호출). 점(.) 구분자는 PostgreSQL 실제 테이블 생성 시 밑줄(_)로 자동 변환되어 school_student 테이블이 생성됩니다.
  • _description: 관리자 화면 및 감사 로그(Audit Trail)에 표시되는 모델의 사용자 친화적 명칭입니다.
  • models.Model: PostgreSQL 데이터베이스에 테이블이 영구 저장되는 기본 영속 모델 클래스입니다 (TransientModel, AbstractModel과 구분).

 👉 [이전 글: Odoo ORM 기본 개념 및 핵심 메서드 7가지] 

 

2. Odoo 기본 필드 타입 (Basic Field Types) 사양

Odoo 필드는 PostgreSQL의 데이터 타입(Data Type)과 직접 매핑되며, 유효성 검증 및 웹 UI 렌더링 방식을 제어합니다.

필드 타입 PostgreSQL 매핑 타입 주요 기술 옵션 및 설명 실무 코드 예시
Char VARCHAR 단일 행 텍스트, size, trim 옵션 지원 fields.Char(required=True, index=True)

Text TEXT 다중 행 장문 텍스트, 개행 지원 fields.Text(string="비고 메모")

Integer INTEGER 32비트 정수형 숫자 fields.Integer(default=0)

Float NUMERIC / FLOAT8 부동소수점 및 통화 단위 소수, digits 정밀도 지정 fields.Float(digits=(16, 2))

Boolean BOOLEAN 참/거짓 값 (체크박스 UI) fields.Boolean(default=True)

Date DATE 연·월·일 날짜 데이터 (시간 미포함) fields.Date(default=fields.Date.today)

Datetime TIMESTAMP WITHOUT TIME ZONE UTC 기준 저장 날짜/시간 (UI에서 로컬 타임존 변환) fields.Datetime(default=fields.Datetime.now)

Selection VARCHAR 사전 정의된 Key-Value 튜플 목록 중 단일 선택 드롭다운 fields.Selection([('draft','임시'),('done','완료')])

 

3. 관계형 필드 타입 3종 (Relational Fields) 완벽 비교

관계형 필드는 관계형 데이터베이스(RDBMS)의 외래키(Foreign Key) 제약 조건과 조인(JOIN) 테이블 관계를 객체 지향적으로 구성합니다.

① Many2one (다대일 외래키 연결)

다수의 현재 모델 레코드가 대상 모델의 단일 레코드를 참조하는 관계입니다. 데이터베이스 레벨에서 대상 테이블을 가리키는 Foreign Key(FK) 컬럼이 생성됩니다.

Python
 
# 주문(Order) 모델에서 단일 고객(Partner)을 참조
partner_id = fields.Many2one(
    comodel_name='res.partner',
    string='Customer',
    ondelete='restrict',
    required=True
)
  • 동작 원리: 실제 PostgreSQL 테이블에는 partner_id INT REFERENCES res_partner(id) 외래키 컬럼이 추가됩니다.

② One2many (일대다 가상 관계)

단일 레코드가 대상 모델의 여러 레코드를 하위 목록으로 참조하는 관계입니다. 물리적 컬럼이 생성되지 않는 가상(Virtual) 필드이며, 대상 모델의 Many2one 필드를 반대편에서 참조(Inverse)합니다.

Python
 
# 고객(Partner) 모델에서 자신의 주문 목록(sale.order)을 역방향 조회
order_ids = fields.One2many(
    comodel_name='sale.order',
    inverse_name='partner_id',
    string='Sales Orders'
)
  • 동작 원리: sale.order 테이블에 존재하는 partner_id를 기반으로 ORM이 서브쿼리를 실행하여 목록을 레코드셋으로 바인딩합니다.

③ Many2many (다대다 양방향 연결)

여러 레코드가 서로 다대다 관계로 자유롭게 연결되는 구조입니다. RDBMS 정규화 원칙에 따라 Odoo가 두 테이블의 ID를 관리하는 중간 조인 테이블(Intermediate Table)을 자동 생성합니다.

Python
 
# 학생(Student) 모델에서 수강 과목(course.course) 다대다 매핑
course_ids = fields.Many2many(
    comodel_name='course.course',
    relation='student_course_rel',  # 중간 테이블 명 (선택)
    column1='student_id',           # 현재 모델 FK 컬럼 (선택)
    column2='course_id',            # 대상 모델 FK 컬럼 (선택)
    string='Courses'
)

 

4. 관계형 필드 선택 및 아키텍처 판별 기준

실무에서 데이터 스키마를 구성할 때는 데이터의 소유권과Cardinality(기수성)에 따라 필드를 정의해야 합니다.

[Many2one]  Order N ─────── 1 Customer      (물리 FK 생성)
[One2many]  Customer 1 ────··· N Orders     (역참조 가상 필드)
[Many2many] Student N ─────··· N Course     (중간 연결 테이블 자동 생성)
  1. 단일 외래키 참조가 필요한 경우: Many2one 사용 (예: 주문의 담당자, 전표의 통화 단위)
  2. 부모-자식(Master-Detail) 구조의 하위 라인을 묶을 경우: One2many 사용 (예: 세금계산서의 품목 상세 라인)
  3. 태그, 권한 그룹, 다중 카테고리 분류가 필요한 경우: Many2many 사용 (예: 고객 태그, 수강 과목 등록)