PostgreSQL Docker 컨테이너 연결 & geojson type 설정

hazelnut·2022년 9월 16일
0
post-thumbnail

PostgreSQL 컨테이너 생성

1. postgres 이미지 내려받기

docker pull postgres:latest

2. 컨테이너 실행

docker run --name [컨테이너 이름] -e POSTGRES_PASSWORD=[Postgres 비밀번호] -d -p [호스트 포트]:5432 postgres:latest

3. 컨테이너 접속

docker exec -it [컨테이너 이름] bash

4. postgres 접속

psql -U postgres

5. Database 생성

postgres=# CREATE DATABASE [데이터베이스 이름];

\list로 database 리스트를 조회할 수 있다.

6. Database 사용

postgres=# \c [데이터베이스 이름]
You are now connected to database [데이터베이스 이름] as user "postgres".

7. Role 생성(필요한 경우)

postgres=# CREATE ROLE [Role 이름] with LOGIN PASSWORD ['비밀번호'];

\du로 role 리스트를 조회할 수 있다.


TypeORM Configuration

TypeOrmModuleOptions

import { TypeOrmModuleOptions } from '@nestjs/typeorm';
import { readFileSync } from 'fs';
import * as path from 'path';
import * as yaml from 'yaml';

const ymlPath = path.join(__filename, '..', 'config.yml');
const config = yaml.parse(readFileSync(ymlPath, 'utf8'));

export const typeormConfig: TypeOrmModuleOptions = {
  type: config[process.env.NODE_ENV || 'local']['db']['type'],
  host: config[process.env.NODE_ENV || 'local']['db']['host'],
  port: config[process.env.NODE_ENV || 'local']['db']['port'],
  username: config[process.env.NODE_ENV || 'local']['db']['username'],
  password: config[process.env.NODE_ENV || 'local']['db']['password'],
  database: config[process.env.NODE_ENV || 'local']['db']['database'],
  autoLoadEntities: true,
  entities: ['dist/entities/*.entity{.ts,.js}'],
  keepConnectionAlive: true,
  logging: config[process.env.NODE_ENV || 'local']['db']['logging'],
  synchronize: config[process.env.NODE_ENV || 'local']['db']['synchronize'],
};
  • autoLoadEntities(boolean): 엔터티 자동 로드 여부
  • entities: 연결 로드할 엔터티 path 목록
  • keepConnectionAlive(boolean): 연결을 재시도할 때마다 에러 메시지 출력 여부
  • logging(boolean): 콘솔에 쿼리로그 출력 여부
  • synchronize(boolean): 엔터티 업데이트 후 DB 스미카 자동 반영 여부

Migration 과정에서 발생한 Error

typeorm postgres type "geometry" does not exist

<수정 전>

@Column({
  name: 'geom',
  type: 'geometry',
  srid: 5186,
  nullable: false,
  comment: 'geom',
})
geom: any;

가장 처음에 정의한 geometry 타입의 컬럼이다. 마이그레이션 시 위와 같이 postgres에 geometry 타입이 없다고 에러가 뜬다. TypeORM 문서에서 postgres 데이터 타입으로 geometry, geography와 같은 타입도 지원하는 것으로 나와 있기 때문에 type에 'geometry'로 작성하면 무방할 줄 알았다.

위 에러문을 검색했을 때 postgres의 postgis extension을 설치해주어야 한다는 글들이 가장 많이 보였다.

postgres=# CREATE EXTENSION "postgis";
ERROR:  could not open extension control file "/usr/share/postgresql/14/extension/postgis.control": No such file or directory

하지만 파일이나 디렉터리를 찾을 수 없다고 나와 다른 방법을 찾아보았고, TypeORM 문서에 안내된 컬럼 데코레이터 옵션(spatialFeatureType)과 npm geojson 패키지를 통해 해결할 수 있었다.

  • spatialFeatureType: string - Optional feature type (Point, Polygon, LineString, Geometry) used as a constraint on a spatial column. If not specified, it will behave as though Geometry was provided. Used only in PostgreSQL.
    👉 공간 데이터 컬럼의 타입으로 지정하기 위한 속성이다. 명시하지 않으면 제공된 Geometry 값 그대로 적용되며, 해당 속성 옵션은 PostgreSQL에서만 지원한다.

  • srid: number - Optional Spatial Reference ID used as a constraint on a spatial column. If not specified, it will default to 0. Standard geographic coordinates (latitude/longitude in the WGS84 datum) correspond to EPSG 4326. Used only in PostgreSQL.
    👉 Spatial Reference Identifier의 약자로, 공간 데이터 컬럼의 타입 제어에 사용된다. 명시하지 않으면 default 값 0이 적용된다. 표준 지리 좌표는 EPSG 4326이며, 이 속성 옵션 또한 PostgreSQL에서만 지원한다.

  • npm geojson
    geo data를 GeoJSON으로 변환하는 패키지이다. GeoJSON은 지리 데이터를 담는 JSON 포맷의 데이터 타입이다. geometry에는 Point, LineString, Polygon, MultiPoint, MultiLineString, MultiPolygon이 있다.

<수정 후>

import { Geometry } from 'geojson';

...

@Column({
  name: 'geom',
  type: 'point',
  spatialFeatureType: 'Point',
  srid: 5186,
  nullable: false,
  comment: 'geom',
})
geom: Geometry;

QueryFailedERROR: function uuid_generate_v4() does not exist

PostgreSQL에서는 uuid-ossp라는 extension을 통해 아래처럼 정의한 PK 컬럼의 uuid를 제공하는데 해당 extension이 존재하지 않는다고 하는 에러이다.

@PrimaryGeneratedColumn('uuid', {
  name: 'project_id',
  comment: '프로젝트 인덱스',
})
projectId: string;

이를 해결하기 위해 먼저 docker postgres 컨테이너에 접속해 사용 가능한 extension 리스트를 확인했다.

[Database 이름]=# SELECT * FROM pg_available_extensions;

확인한 결과, uuid-ossp가 존재했고 이를 활성화하는 쿼리를 실행해 해결했다. 이때 extension을 설치하고자 하는 데이터베이스에 들어가서 실행해야 한다.

[Database 이름]=# CREATE EXTENSION "uuid-ossp";
CREATE EXTENSION
profile
💡 It is wise to direct your anger towards problems, not people; to focus your energies on answers, not excuses. ⏤ William Arthur Ward

0개의 댓글