본문 바로가기
golang

[후기] entgo 두달 사용 후기

by marble25 2022. 7. 23.

golang으로 db에 접근하기 위해서 entgo를 사용해 보았다. 

사실 약 두 달 정도 사용해본 터라 query optimization까지는 가지 못했고, 기본적으로 제공해주는 함수를 이용해서 쿼리, insert 등의 작업을 진행했다.

 

설치


https://entgo.io/docs/getting-started

 

Quick Introduction | ent

ent is a simple, yet powerful entity framework for Go, that makes it easy to build

entgo.io

 

설치의 경우에는 간단하게

go install entgo.io/ent/cmd/ent@latest

와 같이 할 수 있다. 

 

 

구조


go generate ./ent

를 통해 현재 schema 내의 파일을 바탕으로 다른 파일을 생성한다.

따라서 <project>/ent/schema/ 내의 파일들이 source of truth가 되어 다른 파일들을 생성하게 된다.

ent
├── client.go
├── config.go
├── context.go
├── ent.go
├── generate.go
├── mutation.go
... truncated
├── schema
│   └── user.go
├── tx.go
├── user
│   ├── user.go
│   └── where.go
├── user.go
├── user_create.go
├── user_delete.go
├── user_query.go
└── user_update.go

generate시 다음과 같이 엄청나게 많은 파일들이 생성되게 된다.

만약 git system을 사용한다면 스키마를 약간만 변경해도 엄청난 파일 변화를 만들어내게 된다.

따라서 ent 폴더 밑에 다음과 같이 gitignore를 만들어놓는 것을 추천한다.

# Ignore everything
*

# But not these files...
!tests/*
!mixin/*
!schema/*
!.gitignore
!generate.go

schema와 tests, mixin, .gitignore, generate.go 파일만 git에 포함하겠다는 이야기이다.

이런 식으로 적용하면 schema를 변경하더라도 변경한 부분만 깃에 포함되게 된다.

 

+ 추가적으로 작업하면서 스키마 변경을 자주하는 경우 스키마끼리 꼬이는 경우가 많다. ent 폴더가 있는 디렉터리에서 다음 명령을 실행해보자.

find ./ent/ -not -path "*/schema*" -not -path "*generate.go" -not -path "*/mixin*" -not -path "*.gitignore" -not -path "*/tests*" -mindepth 1

추가적으로 삭제를 원하지 않는 파일이 있으면 비슷한 패턴으로 추가하면 된다.

꼼꼼히 파일을 확인후에 위에 나열된 파일을 삭제해본다.

find ./ent/ -not -path "*/schema*" -not -path "*generate.go" -not -path "*/mixin*" -not -path "*.gitignore" -not -path "*/tests*" -mindepth 1 -exec rm -rfs {} \;

그 후, 다시 schema로부터 generate해준다.

go generate ./ent

 

특징


공식 홈페이지에는 다음과 같이 특징이 소개되어 있다.

 

  • Easily model database schema as a graph structure.
  • Define schema as a programmatic Go code.
  • Static typing based on code generation.
  • Database queries and graph traversals are easy to write.
  • Simple to extend and customize using Go templates.

 

여기서 가장 중요한 특징은 graph structure이다.

entgo와 직접 연결할 수 있는 데이터베이스는 mariadb, mysql, postgres, sqlite3 등 다양하다.

하지만 뒷단에 어떤 dbms가 붙든 상관없이 entgo는 graph 형식으로 내부적으로 데이터를 표현하고, dbms에 실제 write할 때에만 row 형식으로 저장하게 된다.

그래서 entgo 공식 홈페이지에서 설명할 때에도 entity와 entity 사이를 edge로 연결한다.

흔히 아는 foreign key는 From/To의 관계로 표현된다. 항상 프로그래밍하면서 어떤 entity에서 edge가 출발하고, 어떤 entity에 edge가 도착하는지 유의하면서 작성해야 한다.

 

비교


이전에는 python django의 기본 orm을 사용해 보았는데, 이와 비교해 보았다.

 

  • 속도

동일한 조건에서 performance 테스트를 한 경험은 없다. django의 경우 쿼리 조회가 살짝 느리다는 느낌을 받은 적이 있지만, entgo는 아직까지 없다. 다만 이는 실질적인 테스트를 기반으로 한 것이 아니고, django 프로젝트의 테이블이 훨씬 컸기 때문일 수도 있으니 실질적인 비교는 어렵다. 

  • 편리성

entgo로 개발하면서 상당히 불편하다고 느낀 포인트가 많았다. 다른 사람의 스키마 변경이 db에 제대로 적용되지 않는 경우가 허다했다. django의 경우에도 migration 파일이 엉키는 경우가 있었지만 훨씬 정도가 덜했고 따라서 db 초기화를 하는 경우는 극히 드물었지만, entgo의 경우 스키마 변경 코드가 로컬로 들어오는 경우 대개 디비 초기화(drop database)를 해야 했다. migration하는 부분이 아직 아쉬움이 컸다.

또한, 스키마 변경에 따른 사용하는 함수 이름 변경이 너무 귀찮았다. 예컨대, m2m(many to many) -> o2m(one to many) 방식으로 edge를 변경했을 때, insert, select 등을 작업할 때 add~~~ 에서 set~~~ 로 함수를 모두 변경해야 했다. 스키마의 작은 변경으로도 연결되는 함수가 모두 변경되어 이와 관련된 코드 모두를 손봐야 하는 것은 분명 문제가 있었다.

  • 기능

django가 훨씬 다양한 기능을 제공하는 것으로 보인다. django는 체이닝을 통해 다양한 기능을 붙일 수 있었지만, entgo는 기본적인 기능만 붙일 수 있었다. 하지만 일반적으로 생각할 수 있는 기능들은 둘다 쉽게 제공하기 때문에 사용에 불편함을 겪을 정도는 아니었다.

  • 난이도

사실 난이도 자체는 django와 entgo 모두 낮은 편이라고 판단한다. 

 

총평


처음에는 db와 go를 직접 연결해서 사용해 보았는데 확실히 너무 귀찮은 작업들이 많아서 orm을 도입하게 되었다.

orm 도입 이번보다는 훨씬 작업이 간편해졌다. 하지만, 다른 사람 코드를 받아올 때마다 거의 db 스키마를 다 날리고 작업해야 하는 점과, 스키마의 작은 변경이 실제 사용하는 코드에 많은 변경을 낳는 등의 단점이 보였다.

이러한 단점이 해결된다면 훨씬 편리할 것 같다.

'golang' 카테고리의 다른 글

goroutine 파헤치기  (0) 2023.09.23
Formatting in golang  (0) 2023.09.03
Internal package in golang  (0) 2023.09.03
Go 언어를 활용한 분산 서비스 개발  (0) 2023.07.23
실무에 바로 쓰는 Go 언어 핸즈온 가이드  (0) 2023.07.12