Postgresql 데이터 csv로 저장 및 csv데이터 insert하기

쿼리결과 csv 파일로 저장하기

Database: Postgresql
실행환경: Docker

  1. psql 접속하여 실행하는 법

    1
    2
    3
    4
    5
    6
    7
    docker exec -it <데이터베이스 컨테이너> bash

    # 컨테이너 접속 후
    psql -U <name> -d <database>

    # psql 접속 후
    COPY (select * from <tablename>) To '/path/fiilename.csv' With CSV DELIMITER ',' HEADER;
  2. 스크립트 작성으로 만들기

    1
    2
    3
    4
    5
    6
    docker exec <데이터베이스 컨테이너> \
    su - postgres -c \
    '
    psql -U <username> -d "<database name>" \
    -c "COPY (select * from <table name>) To '"'/path/fiilename.csv'"' With CSV DELIMITER '"','"' HEADER; "
    '

    주의사항: 따옴표 내부에서 문자열 조건이나 경로 입력 시 ‘“‘문자열’”‘로 감싸서 작성해야 문자열로 인식한다.

csv 파일 import 하기

  1. psql 접속하여 실행하는 법

    1
    2
    3
    4
    5
    6
    7
    docker exec -it <데이터베이스 컨테이너> bash

    # 컨테이너 접속 후
    psql -U <name> -d <database>

    # psql 접속 후
    COPY <tablename> FROM '/path/filename.csv' DELIMITER ',' CSV HEADER;
  2. 스크립트 작성으로 만들기

    1
    2
    3
    4
    5
    6
    docker exec <데이터베이스 컨테이너 이름> \
    su - postgres -c \
    '
    psql -U <username> -d "<database name>" \
    -c "COPY <table name> FROM '"'/path/filename.csv'"' DELIMITER '"','"' CSV HEADER; "
    '

스크립트 작성 중 알게 된 것
도커로 실행하는 레일스 앱에 스크립트에서 명령을 실행하기위해서는 다음과 같이 작성한다.

1
2
3
docker exec -i <container> rails c <<EOF
# 실행하고 싶은 명령어
EOF

Ruby on Rails Docker Setting (레일스 도커 개발환경 세팅하기)

Ruby on Rails Docker Setting

레일스 개발 환경을 도커로 세팅해보자

크게 복잡하고 거창한 환경 세팅은 아니지만 처음 세팅이 항상 골칫거리이다..

개발 환경
ruby-on-rails -v 7.0^
ruby -v 2.7.1
RubyMine
Docker
docker-compose
postgres -v 14.2-alpine

1. 기본 세팅을 위한 파일 생성 및 작성

1
2
3
4
5
6
mkdir backend
cd backend

touch Dockerfile
touch docker-compose.yml
touch docker-compoes.env

Dockerfile 작성

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# syntax=docker/dockerfile:1
FROM ruby:2.7.1

RUN apt-get update -qq && apt-get install -y nodejs postgresql-client

WORKDIR /usr/src/app
COPY Gemfile ./
COPY Gemfile.lock ./
RUN bundle install

# Add a script to be executed every time the container starts.
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000

# Configure the main process to run when running the image
CMD ["rails", "server", "-b", "0.0.0.0"]

docker-compose.yml 작성

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
version: "3"
services:
## backend
database:
image: postgres:14.2-alpine
ports:
- "5432:5432"
env_file: docker-compose.env
volumes:
- ./psql/data:/var/lib/postgresql/data

## api
web:
container_name: web
build: .
command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
ports:
- "3000:3000"
env_file: docker-compose.env
volumes:
- ./:/usr/src/app
depends_on:
- "database"
environment:
- RAILS_ENV=development

Gemfile, Gemfile.lock 생성

1
2
touch Gemfile
touch Gemfile.lock
1
2
3
4
# Gemfile
source "https://rubygems.org"

ruby "2.7.1"

docker-compose.env

1
2
3
4
5
POSTGRES_USER=user
POSTGRES_PASSWORD=password

PG_USER=user
PG_PASSWORD=password

2. 빌드 시작

1
docker-compose build

빌드를 시작해도 아직 레일스 세팅이 안되어있다. docker 컨테이너를 이용하여 레일스 설치를 진행한다.

1
docker-compose run --no-deps web rails new . --api --force --database=postgresql

실행 시 뭔가 쭉쭉 설치되고 로컬 디렉토리와 컨테이너 볼륨을 지정해줬기 때문에 작업 디렉토리에 레일스 폴더, 파일들이 생성된다.



3. database.yml 작성

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# ./config/database.yml

default: &default
adapter: postgresql
encoding: utf8
# For details on connection pooling, see Rails configuration guide
# https://guides.rubyonrails.org/configuring.html#database-pooling
pool: 5
host: database # docker 환경 데이터베이스와 연결을 하기위해서는 컨테이너 이름으로 지정해주어야 한다.
username: juren
password: juren

development:
<<: *default
database: juren_development

test:
<<: *default
database: juren_test

4. 데이터베이스 생성하기

아직 도커에서 실행중인 postgresql 에는 데이터베이스가 생성되어있지 않다. yml 파일에서 지정한 데이터베이스들을 생성해주기 위해서는 아래 명령어를 실행한다.

1
2
docker-compsoe up # 컨테이너 실행 명령어
docker-compose run web rake db:create # rails db 생성 명령어

5. localhost 접속

크롬 -> localhost:3000 접속 결과 확인



끝~👍👍

은 아니고 이제 시작...

Sequelize Migration

도커를 통해 데이터베이스를 띄우고 express를 실행시켜 연결을 해보았다. MySQL과 연결하여 데이터베이스를 사용하기 위해서 Sequelize를 사용하여 연결까지 성공적으로 연결을 진행하였다.

기존에 시퀄라이즈를 사용할때는 모델을 모두 정의한 후 데이터베이스를 생성하고 모델의 수정사항이 있을때마다 **Sync({ force: false || true })**옵션을 통해 데이터베이스를 수정하며 진행했다. 물론 혼자 사용하는 데이터베이스고 서비스를 하지 않는 디비여서 이런방식으로 사용해도 무방하지만 실무에서 사용하는 데이터베이스는 많은 데이터가 있고 구조의 변경이 일어날때 마다 데이터를 백업한다던지 새로 덤프 한다는 것은 현실적으로 어려움이 있다.

이러한 문제점을 보완하기 위해 ORM에서는 마이그레이션 기능을 지원한다. 마이그레이션이란 어떤 운영환경에서 다른 환경으로 환경의 변화를 위해 옮겨지는 작업을 의미한다.

데이터베이스 마이그레이션이란.

데이터베이스 마이그레이션이란 하나의 데이터베이스를 다른 종류의 데이터베이스로 데이터를 옮기는 경우 혹은 두개의 데이터베이스를 하나의 시스템으로 합치거나 분할 혹은 데이터베이스 모델의 구조적 변경을 진행 하는 모든 과정을 의미한다.
데이터 베이스 마이그레이션이란?

그렇다면 시퀄라이즈에서 제공하는 Migration 기능에는 어떤 기능이 있을까? 시퀄라이즈에서는 몇가지 명령어를 통해 마이그레이션 기능을 사용할 수 있다고 한다.

자세히 보기

Doker Mysql(sequelize)

Docker MySQL Express 연결하기

이전 도커로 express앱을 띄운 후 연결 확인 후 데이터 베이스를 도커로 실행 한 후 express와 연결하는 테스트를 진행해보도록 하자.

먼저 docker-compose.yml에 mysql이미지를 추가해준다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
mysql:
image: mysql:5.7
command:
--default-authentication-plugin=mysql_native_password
--character-set-server=utf8mb4
--collation-server=utf8mb4_unicode_ci
restart: always
environment:
MYSQL_DATABASE: # Database Name
MYSQL_USER: # User name
MYSQL_PASSWORD: # Password
MYSQL_ROOT_PASSWORD: # Root Password
ports:
- "3306:3306"
volumes:
- ./data:/var/lib/mysql
- ./mysql.conf:/etc/mysql/conf.d

docker-compose up 명령 실행 후 mysql이 실행중인 것을 확인하고 docker exec -it #{name} bash 를 통해 mysql로 접근이 가능하다.

자세히 보기

Docker Node.js nodemon

도커를 활용하여 Express를 구동하기 위해 이전 포스팅을 통해 기본적인 앱을 띄워 보았다. 도커를 통해 express를 실행하였지만 코드의 수정이 있을 때 마다 빌드를 다시 해주어야 하는 문제점이 있었다.
node.js에서는 nodemon이라는 모듈을 사용하여 개발환경에서 코드의 변경사항이 감지되었을때 자동으로 코드의 반영사항을 포함하기 위해 서버를 재시동 해주며 개발을 진행한다.

도커를 통해 띄운 express를 로컬에서 작업 후 변경사항을 반영해주기 위해서는 도커의 작업 디렉토리와 로컬 작업 디렉토리를 볼륨 연결 설정을 통해 연결해주고 nodemon으로 express를 구동해주면 된다.

  1. docker-compose.yml
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    version: "3.8"

    services:
    mysql:
    image: mysql:5.7
    command:
    --default-authentication-plugin=mysql_native_password
    --character-set-server=utf8mb4
    --collation-server=utf8mb4_unicode_ci
    restart: always
    environment:
    MYSQL_DATABASE: test
    MYSQL_USER: test
    MYSQL_PASSWORD: 1210ss
    MYSQL_ROOT_PASSWORD: 1210ss
    ports:
    - "3306:3306"
    volumes:
    - ./data:/var/lib/mysql
    - ./mysql.conf:/etc/mysql/conf.d

    docker-test:
    build:
    context: .
    args:
    PORT: "4000"
    image: docker-node-app
    container_name: docker-node-app
    volumes:
    - .:/usr/src/app
    - /usr/src/app/node_modules
    ports:
    - "1210:4000"
    docker-compose.yml 파일을 통해 여러 컨테이너를 한번에 관리해주는 방식으로 하나의 서비스를 위해 실행하거나 존재해야하는 이미지들을 한 파일을 통해 정의하는 방식이다.

mysql은 이 후 사용할 예정이므로 넘어가도록 하고 volumes옵션이 중요한 부분이다.

volumes은 다음과 같이 작성해 주면된다. <로컬 작업 디렉토리>:<도커 컨테이너 디렉토리> 이것은 로컬 디렉토리와 도커의 디렉토리를 연결하겠다는 의미로 코드의 변경이나 생성 삭제와 같은 작업의 결과를 공유해준다.

이 후 nodemon을 통해 express 를 실행하고 로컬에서 작업 후 변경사항이 생기게 되면 도커에서 실행중인 express가 재시동 되며 수정 사항을 반영하게 된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
FROM node:12

ARG PORT
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

# . 은 현재 디렉토리의 모든것을 /usr/src/app으로 복사한다는 의미다.
COPY . /usr/src/app
RUN npm install

RUN npm install -g nodemon
# Bundle app source

EXPOSE $PORT

# 도커에서 nodemon을 실행하기 위해 필요한 옵션
CMD ["nodemon", "-L", "app.js"]

컨테이너를 다시 빌드 후 접속하고 코드를 수정하면 변경사항이 자동으로 반영되는 모습을 확인 할 수 있다.

Docker 개발환경 세팅하기

Docker 개발 환경 구축

회사에서 처음 클론 받은 레포지토리의 개발 환경 구축을 위해 도커환경을 구축하며 사용하던 명령어들과 도커를 이용하여 프로젝트 환경을 세팅하는 기본적인 것들에 대해서 기록하고자 글을 남깁니다.

자세히 보기