/ PROJECT, WANTED, WECODE

백엔드 프리온보딩 2주차 첫번째 프로젝트 회고


원티드 2주차 원티드 기업과제


진행기간

21.11.08 ~ 21.11.10


구현해야 하는 기능

  • 회사명 자동 완성
    • 회사명의 일부만 들어가도 검색이 되어야 한다
  • 회사 이름으로 회사 검색

  • 새로운 회사 추가

나의 역할

  • 회사 추가 기능
    • 언어별로 추가되는 회사, 태그 추가하기
  • unit test 구현
  • README.md 작성

배운내용

  • flask
  • 다대다 참조시 중계 테이블 생성
  • 리펙토링의 중요성

프로젝트 회고

이번 원티드의 기업과제에서 내가 개발해야 하는 기능은 추가되는 회사를 언어별로 따로 추가해주어야 하고 각 언어별 회사의 태그를 추가해주는 기능이였다.

이번과제 역시 모델링 설계가 중요했지만 유독 더 중요했던 과제였다. 회사는 동일한데 각 회사가 가지고 있는 언어별로 기업을 추가해주어야 했고 태그 또한 각 언어별로 태그가 추가되어야 했다. 더군다나 flask를 사용하기로 했기 때문에 모델링이 더욱 중요해질 수 밖에 없었다. 회의만 2시간 넘게 진행한 것 같다.

여기서 팀원들의 의견이 갈렸었다. company라는 테이블에 모든 데이터를 넣어야 하는가 테이블을 나누어야 하는가로 의견이 갈렸다. 하지만 하나의 테이블로 만들때 생기는 문제점이 여러개 있을 수 있었고 이를 고려하여 최대한 테이블을 나누어 설계하는 쪽을 택했다.

아래의 이미지와 같이 모델링 설계를 진행했으며 다대다로 엮인 중계 테이블을 만들기로 하였다.
wanted_erd

  • 회사를 대표하는 companies라는 테이블과 각 company에 해당하는 언어를 다대다로 참조한 중계테이블인 company_contries 테이블을 생성
  • tag와 여러 언어의 tag를 가지고 있는 tag_contries라는 중계 테이블 생성
  • company와 company가 가지고 있는 tag를 다대다로 참조한 중계 테이블인 company_tags를 생성


이후 회사를 추가할때 회사가 존재하지 않으면 먼저 회사를 추가해주었다.

if not db.session.query(db.session.query(Company).filter_by(name=company_infor[0][1]).exists()).scalar():
            company_entity = Company(name=company_infor[0][1])
            db.session.add(company_entity)
            db.session.commit()

이후 추가하는 회사가 가지고 있어야 하는 언어가 country테이블에 존재하지 않으면 테이블에 추가해주었다

for language, translated_company in company_infor:
    if not db.session.query(db.session.query(Country).filter_by(name=language).exists()).scalar():
        country = Country(name=language)
        db.session.add(country)
        db.session.commit()

이후 company와 country의 중계 테이블에 각 언어에 대한 회사를 생성해주었다

 com_country = company_countries.insert().values(
    country_id=country.id,
    company_id=company_entity.id, 
    translated_name=translated_company 
)
db.session.execute(com_country)
db.session.commit()

태그 기능 또한 위의 로직과 같이 진행했다.



flask의 사용

원티드 기업에서 권장하는 프레임워크가 flask였고 flask의 경험이 대부분 없었지만 이번 프로젝트에는 flask를 사용해보기로 했다. 생각보다 장고와 다른점이 꽤 있었다

  • 장고처럼 필요한 파일(models.py, urls.py…)을 자동으로 생성해주지 않는다
  • 모델 설계시 문법이 꽤 다르다
  • ORM문법 또한 장고와 다른 부분이 있다
  • url 파일이 따로 없어 view에서 url을 작성한다

flask의 restful을 사용해서 기능 개발을 하기로 결정했고 필요한 파일들은 직접 만들기로 했다. 이때 MVC의 패턴에 따라 controller라는 폴더를 생성해 이곳에서 view를 작성했다.

모델링 설계할땐 모든 팀원이 진짜 머리를 맞대고 함께 방법을 찾아냈다. 같이 하면서 정말 좋았던 점은 혼자서는 이렇게 짧은 시간안에 못했을 것을 짧은 시간안에 구현해낼 수 있다는 것이다.

데이터베이스에 대한 접근은 SQLAlchemy를 사용해 ORM으로 사용했다. (짧은 시간안에 DB를 다루기 위해서는 ORM이 진짜 좋은 것 같다..^^)


리펙토링 후 코드

이후 팀원의 피드백을 받아 코드를 전체적으로 리펙토링 하는 시간을 가졌다. 함께해서 좋은 점은 내 코드에 대한 피드백을 주고 받을 수 있다는 것이다.

  • 코드의 가독성에 더 많은 신경을 쓰게 된다
  • 코드를 왜 그렇게 짰는지에 대한 이유를 생각하게 된다
  • 더 개선된 로직을 짤 수 있게 된다

  • 회사정보를 가져올때 인덱스를 이용해야 하기 때문에 0,1로 나타내기 보다는 상수로 정해서 어떤 종류의 인덱스로 가져오는지 알 수 있게 설정한다
FIRST_INPUT = 0
VALUE_IDX = 1

company_infos = list(data["company_name"].items())
    company = Company.query.filter_by(
        name=company_infos[FIRST_INPUT][VALUE_IDX]
    ).first()
    
    if company:
        return {"message": "Company Already Exist"}, 404


  • 회사가 테이블에 존재하지 않으면 새롭게 테이블에 추가해준다. 이때 filter_by와 first로 company가 있는지 없는지 확인하는 로직이 좀 더 가독성 면에서 좋다. 태그 기능도 마찬가지로 first를 사용하는게 동일한 효과를 가져올 것 같다
if not Company.query.filter_by(name=company_infos[FIRST_INPUT][VALUE_IDX]).first()
    company = Company(name=company_infos[FIRST_INPUT][VALUE_IDX])
    db.session.add(company)



아쉬웠던 점

태그기능을 구현하는데 있어 충분한 커뮤니케이션이 되지 않아 서로 이해했던 방향이 달랐다.
나는 회사를 추가할때 추가되는 태그가 무조건 새로운 태그네임이라고 판단하고 태그를 테이블에 언어별로 create해주는 로직으로 작성했다. 이후 서로의 코드를 함께 보는 시간에 한 팀원이 태그 테이블에 추가시키려는 태그가 있을 수 도 있는거 아니냐는 이야기를 했다. 태그가 존재하면 새로운 태그는 추가시키지 않는 방향이 태그의 역할과 더 어울릴 것 같다는 의견을 내주었다.

시간이 없어 태그가 새롭게 추가되는 방향으로 로직구현을 마무리 지었다. 의견을 듣고 다시 생각해보니 태그의 역할을 생각해보면 새로운 태그가 추가될 수도 있지만 아닐수도 있다는 생각을 가지게 되었다. 이부분을 사전에 팀원들과 함께 회의를 통해 제대로 정했어야 했지만 그 부분이 부족했다.

내가 생각한 방향이 다른 사람과 같지 않을수도 있다는 것을 다시 한번 깨닫게 되었고 다음부턴 이런 부분까지 함께 회의를 통해 맞추는 자세가 필요할 것 같다



진행한 소감

이번에도 연속으로 밤을 새게 되었다. 긍정적으로 생각한다면 저번 과제에 걸린 시간보다 약 2시간 일찍 마쳤다는점, 그리고 저번 과제 때보다는 서로 기분을 이해하려고 애쓴게 보였다는 점이다. 협업 경험이 많지 않은 사람들끼리 만나 서로 다른 코딩 스타일이나 컨벤션을 맞추기 위해 코드를 몇번이나 재확인하고 git의 충돌로 이를 해결하고 잘 안되는 부분 같이 고민하고..

확실히 저번보다는 나아졌지만 아직 미숙한 부분들이 있기에 이를 맞춰가는 과정이라고 생각한다. 무엇보다 협업 을 하기 위해서는 전달력이 좋아야 할 것 같다는 생각이 들었다. 그러기 위해서는 내 의견을 팀원들이 한번에 이해할 수 있게 말하는 연습도 필요했다. 그래야 기능을 개발할때 혼란이 생기지 않는다. (위에 아쉬운 점이 앞으로 없기 위해서는 더욱 중요하다 ㅠㅠ)

다음번에는 밤 새지 않고 끝내는 것을 목표를 해야겠다 !