[Vapor/Swift] Local에서 PostgreSQL DB 구성하기

Ryan (Geonhee) Son·2021년 7월 6일
0

서버를 배포하는 작업은 시간이 많이 소요되므로 로컬에서 작업한 후 원격 환경에 배포하는 방법을 고려해볼 수 있습니다. 따라서 이번에는 로컬 환경에서 PostgreSQL을 Vapor의 DB 드라이버로 설정하고 마이그레이션 하는 방법을 알아보겠습니다. 먼저 작성하기에 앞서 이 글을 참고하여 작성하였음을 밝힙니다.

Local 환경 PostgreSQL DB 구성

PostgreSQL 설치

PostgreSQL을 사용하기 위해 먼저 brew를 통해 PostgreSQL을 다운로드 받습니다. 터미널에 아래와 같이 명령하시면 됩니다.

brew install postgresql

설치가 완료되시면 터미널을 통해 아래와 같이 명령합니다.

pg_ctl -D /usr/local/var/postgres start

// postgresql 서비스 시작
brew services start postgresql

// 재실행 시
brew services restart postgrsql

PostgreSQL 기본 문법

// PostgreSQL 접속
psql postgres 

// 모든 데이터베이스 조회
postgres=# \l 

// 데이터베이스 생성
postgres=# create database my_database

    // 명령어를 입력했지만 데이터베이스가 생성되지 않은 경우 \q 명령을 통해 접속 해제하신 후
    // 터미널에 아래 명령을 입력하시고 다시 접속하여 db가 생성되었는지 확인해보시기 바랍니다.
    createdb (database_name)
    
// PostgreSQL 접속 해제
postgres=# \q

// 작성한 데이터베이스로 이동
postgres=# \c (database_name)

// 테이블 목록 조회
my_database=# \dt

// 테이블 내 모델 인스턴스 조회
my_database# select * from (table_name);
    // 테이블 이름을 대소문자를 혼용하여 지으셨다면 "table_name"과 같이 테이블 이름 전후로 쌍따옴표를 붙여 명령어를 입력해주세요.

// 테이블 삭제
my_database=# drop table (table_name)

데이터베이스 생성

위 기본 문법을 참고하셔서 데이터베이스를 하나 생성해주세요. postgreSQL에 접속된 상태에서 \l 명령을 통해 데이터베이스가 생성되었는지 확인도 해주시면 좋습니다.

Owner 값도 이후 과정에서 사용될 예정이니 기억해두시면 좋습니다.

SPM Package.swift에 PostgreSQL 의존성 추가

터미널에서 vapor new (ProjectName) 명령을 통해 Vapor 프로젝트를 생성하실 때 Fluent를 추가하시고 PostgreSQL 사용을 선택하시지 않은 경우 Package.swift 파일에서 아래와 같이 의존성을 추가해주세요. ⭐️로 표시한 내용을 참고하시면 됩니다.

// swift-tools-version:5.2
import PackageDescription

let package = Package(
    name: "ProjectManagerServer",
    platforms: [
       .macOS(.v10_15)
    ],
    dependencies: [
        // 💧 A server-side Swift web framework.
        .package(url: "https://github.com/vapor/vapor.git", from: "4.0.0"),
        // ⭐️ Fluent 프레임워크 의존성을 추가하지 않으신 경우 아래 추가
        .package(url: "https://github.com/vapor/fluent.git", from: "4.0.0-rc"),
        // ⭐️ Fluent Postgres 드라이버 의존성 추가
        .package(url: "https://github.com/vapor/fluent-postgres-driver.git", from: "2.0.0"),
    ],
    targets: [
        .target(
            name: "App",
            dependencies: [
                .product(name: "Vapor", package: "vapor"),
                // ⭐️ Fluent 프레임워크 추가 시 아래 내용 추가
                .product(name: "Fluent", package: "fluent"),
                // ⭐️ Fluent Postgres 드라이버 추가 시 아래 내용 추가
                .product(name: "FluentPostgresDriver", package: "fluent-postgres-driver")
            ],
            swiftSettings: [
                // Enable better optimizations when building in Release configuration. Despite the use of
                // the `.unsafeFlags` construct required by SwiftPM, this flag is recommended for Release
                // builds. See <https://github.com/swift-server/guides#building-for-production> for details.
                .unsafeFlags(["-cross-module-optimization"], .when(configuration: .release))
            ]
        ),
        .target(name: "Run", dependencies: [.target(name: "App")]),
        .testTarget(name: "AppTests", dependencies: [
            .target(name: "App"),
            .product(name: "XCTVapor", package: "vapor"),
        ])
    ]
)

네트워크가 사용 가능한 환경에 계실 경우 바로 SPM이 의존성을 추가하기 시작할 것입니다.

의존성 추가 작업이 끝나면 App 폴더 내에 위치한 configure.swift로 이동하여 아래와 같이 app.databases를 이용해 DB 구성 작업을 해줍니다. 필요한 프레임워크가 아래처럼 모두 import 되어있는지도 확인해주세요.

import Vapor
import Fluent
import FluentPostgresDriver

public func configure(_ app: Application) throws {
    app.migrations.add(CreateProjectItem()) // 마이그레이션 과정에서 설명할 내용 

    // ⭐️ 아래 내용을 추가하여 로컬 DB를 구성합니다.
    app.databases.use(
        .postgres(hostname: "localhost", username: "ryan-son", password: "", database: "database_name"),
        as: .psql
    )

    try routes(app)
}

매개변수의 전달인자로 사용되는 값은 위와 같이 넣어주시면 됩니다. username의 경우 PostgreSQL에 접속해서 확인하신 owner이름을, password는 기본 패스워드인 ""을 입력해주시면 됩니다. 데이터베이스 이름도 확인하셔서 기입해주세요.

Database Migration

configure.swift를 통해 로컬 환경의 PostgreSQL을 사용함을 알려주었다면, 저희가 이전 과정을 통해 만들어두었던 모델 타입을 담을 수 있는 표(스키마)를 만들어주어야 합니다. 이 과정이 마이그레이션입니다. 마이그레이션은 데이터베이스의 버전 관리 시스템 (Version Control System; VCS)와 같아서 생성할 수도 있지만 이전으로 되돌릴 수도 있습니다. 아래 과정을 계속해서 살펴보죠.

Migration 파일 생성

먼저 Migrations 폴더를 만들고 내부에 Create<SchemaName>.swift와 같은 파일을 생성합니다. 저는 CreateProjectItems.swift로 만들었습니다.

이제 아래와 같이 데이터베이스에 스키마를 생성할 수 있도록 prepare(on:) 메서드를 작성합니다.

import Fluent

struct CreateProjectItem: Migration {
    /// 데이터베이스에 변경을 만드는 메서드
    func prepare(on database: Database) -> EventLoopFuture<Void> {
        return database.schema("projectItems")
            .id()
            .field("title", .string, .required)
            .field("content", .string, .required)
            .field("deadlineDate", .date, .required)
            .field("progress", .string, .required)
            .field("index", .int, .required)
            .create()
    }

    /// 가능한 경우 `prepare`에서 만든 변경사항을 되돌리는(undo) 메서드, 현재는 스키마 삭제로 설정됨
    func revert(on database: Database) -> EventLoopFuture<Void> {
        return database.schema("projectItems").delete()
    }
}

등록 (Register)

위와 같이 마이그레이션 구조체를 작성하셨다면 아래와 같이 configure.swiftapp.migrations를 이용해 마이그레이션을 등록해주어야 합니다.

import Vapor
import Fluent
import FluentPostgresDriver

public func configure(_ app: Application) throws {
    // ⭐️ 아래 내용을 추가하여 작성한 마이그레이션을 등록합니다.
    app.migrations.add(CreateProjectItem())

    app.databases.use(
        .postgres(hostname: "localhost", username: "ryan-son", password: "", database: "database_name"),
        as: .psql
    )

    try routes(app)
}

Migrate

사전 작업이 완료되었다면 터미널에 아래 명령을 입력하여 마이그레이트를 실시합니다.

vapor run migrate

마이그레이션 작업이 완료되었으면 PostgreSQL에 접속하여 테이블을 확인하실 수 있으실 것입니다. 제 테이블에는 넣어둔 내용이 있어 이렇게 보이지만, 여러 분들은 필드 이름만 있고 내용은 빈 테이블을 확인하실 수 있으실 것입니다.

Revert

앞서 말씀드렸듯이 마이그레이션 작업은 버전 관리 시스템과 같아서 마이그레이션 작업을 되돌릴 수 있습니다. Migration 파일 생성 섹션에서 다룬 Migration이 채택된 타입의 revert(on:) 메서드를 커스터마이징하셔서 사용하실 수 있는데, 저의 경우에는 스키마 삭제가 적용되어 있습니다. revert 작업은 터미널에 아래와 같이 명령하시면 수행하실 수 있습니다.

vapor run migrate --revert
profile
합리적인 해법 찾기를 좋아합니다.

0개의 댓글