매드마이그레이션

최근 시작한 데이터베이스 마이그레이션용 오픈소스 프로젝트를 소개하고자 합니다. 많은 데이터베이스 마이그레이션 도구가 존재하는데 왜 그러한 도구가 필요합니까? 자세히 알아보자. 우리는 과거에 만들어진 프로젝트에 몇 가지 새로운 기능을 추가해 달라는 요청을 받았습니다. 프로젝트에 들어가자마자 우리는 데이터베이스 구조가 잘 설계되지 않았고 테이블에 복잡한 문제가 있다는 것을 깨달았습니다. 우리는 데이터베이스 구조를 재설계하고 데이터를 그대로 유지하기로 결정했습니다.
우리는 이 경우에 대한 솔루션을 생성하기 위해 많은 도구를 살펴보았지만 거의 동일하게 작동했습니다. 기본적으로 도구의 절차는 오래된 데이터베이스 구조를 얻고 데이터 유형을 변환하고 데이터베이스 구조를 변경하고 다른 데이터베이스로 전송하는 것입니다. 우리는 새로운 데이터베이스 구조와 데이터를 유지하는 것을 주요 목표로 설계했습니다. 다른 테이블에서 데이터를 가져와 새 테이블로 전송해야 했습니다. 확실히 또 다른 옵션은 오래된 데이터베이스를 덤프하고 거기에서 모든 것을 변경하고 새 데이터베이스로 가져오는 것일 수 있습니다. 다행히 우리는 이 기술을 적용하지 않았고 모든 것을 수행하는 도구를 만들기로 결정했습니다. 그곳에서 이야기가 시작됩니다MadMigration.

MadMigration은 완전히 파이썬으로 작성되었습니다. SQLAlchemy 라이브러리의 힘을 사용했습니다. 이 자습서에서는 MadMigration을 사용하는 방법에 대해 자세히 설명합니다.

설치


pip install madmigration또는pip3 install -U madmigration
버전을 확인할 수 있습니다:madmigration --version
시작하겠습니다.

예를 들어 이름이 user인 이전 MySQL 데이터베이스 테이블이 있습니다.

#Mysql
CREATE TABLE `user` (
  `id` int NOT NULL AUTO_INCREMENT,
  `fname` varchar(10) NOT NULL,
  `lname` varchar(10) NOT NULL,
  `nick` varchar(10) NOT NULL,
  `email` varchar(15) NOT NULL,
  `pass` varchar(15) NOT NULL,
 `updated` TIMESTAMP NULL,
 `created` TIMESTAMP NOT NULL,
  `companyID` INT,
  PRIMARY KEY (`id`),
  FOREIGN KEY (companyID)
  REFERENCES company(`id`)
  ON DELETE SET NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci


그리고 이 테이블을 다른 열 이름을 가진 새 postgresql 테이블로 마이그레이션하려고 합니다.

#postgresql

CREATE TABLE public."User" (
created_at timestamp NOT NULL,
updated_at timestamp NULL,
id serial NOT NULL,
"name" varchar NOT NULL,
surname varchar NOT NULL,
nickname varchar NOT NULL,
email varchar NOT NULL,
"password" varchar NOT NULL,
CONSTRAINT "User_email_key" UNIQUE (email),
CONSTRAINT "User_pkey" PRIMARY KEY (id),
company_id integer REFERENCES company (id)
ON DELETE SET NULL
);


그런 다음 테이블과 열을 선언하기 위한 yaml 파일schema.yml을 만듭니다. 첫 번째 단계에서 Configs 섹션을 추가합니다. 이 섹션은 데이터베이스에 연결하기 위한 것입니다. Configs 섹션에는 SourceConfig , DestinationConfig 두 개의 하위 섹션이 있습니다.

version: 0.1.8
Configs:
  - SourceConfig:
      dbURI: "mysql://root:[email protected]/old"
  - DestinationConfig:
      dbURI: "postgresql://root:[email protected]/new"

migrationTables 섹션은 테이블에 대한 정보를 설명하기 위한 것입니다.

migrationTables:
  - migrationTable:
      SourceTable:
        name: user
      DestinationTable:
        name: User
        create: true 


다음으로 MigrationColumns 섹션에 열에 대한 정보를 작성합니다.

MigrationColumns:
  - sourceColumn:
      name: id
    destinationColumn:
      name: id
      options:
        primary_key: true
        type_cast: bigint

foreign key를 생성하는 경우 열 매개변수에서 지정할 수 있습니다. foreign key 와 같은 ondelete,onupdate 옵션을 정의합니다. table_name 매개변수는 테이블에 대한 참조이고 column_name는 참조된 열의 이름입니다.

  - sourceColumn:
      name: companyID
    destinationColumn:
      name: company_id
      options:
        type_cast: int
        nullable: true
        foreign_key:
          table_name: company
          column_name: id
          ondelete: "SET NULL"


추가된 옵션sourceColumn 섹션이 없지만 destinationColumn 섹션에서 primary_key,nullable,default,index,unique,autoincrement,foreign_key,length,type_cast 옵션을 가질 수 있습니다. 최종 yaml 구조는 다음과 같습니다.

version: 0.1.8
Configs:
  - SourceConfig:
      dbURI: "mysql://root:[email protected]/old"
  - DestinationConfig:
      dbURI: "postgresql://root:[email protected]/new"

migrationTables:
  - migrationTable:
      SourceTable:
        name: user
      DestinationTable:
        name: User
        create: True 

      MigrationColumns:
        - sourceColumn:
            name: id
          destinationColumn: 
            name: id
            options:
              primary_key: true
              type_cast: bigint

        - sourceColumn:
            name: fname
          destinationColumn:
            name: name
            options:
              type_cast: string

        - sourceColumn:
            name: lname
          destinationColumn:
            name: surname
            options:
              type_cast: string

        - sourceColumn:
            name: email
          destinationColumn:
            name: email
            options:
              type_cast: string
              unique: true

        - sourceColumn:
            name: nick
          destinationColumn:
            name: nickname
            options:
              type_cast: string

        - sourceColumn:
            name: pass
          destinationColumn:
            name: password
            options:
              type_cast: string

        - sourceColumn:
            name: updated
          destinationColumn:
            name: updated_at
            options:
              type_cast: datetime

        - sourceColumn:
            name: created
          destinationColumn:
            name: created_at
            options:
              type_cast: datetime

        - sourceColumn:
            name: companyID
          destinationColumn:
            name: company_id
            options:
              type_cast: int
              nullable: true
              foreign_key:
                table_name: company
                column_name: id
                ondelete: "SET NULL"


또한 RDBMS 에서 NOSQL 로 데이터를 마이그레이션할 수 있습니다. 아래는 PostgreSQl 에서 MongoDB 로의 마이그레이션 데이터에 대한 간단한 예입니다. PostgreSQl에서 MongoDB에 대한 작업은 계속 진행 중이며 가능한 한 빨리 다른 기능을 추가할 것입니다.

version: 0.1.8
Configs:
  - SourceConfig:
      dbURI: "postgresql://root:admin@localhost:5432/olddb"
  - DestinationConfig:
      dbURI: "mongodb://localhost:27017/mydb"

migrationTables:
  - migrationTable:
      SourceTable:  #postgresql table name
        name: company  
      DestinationTable: #the collection name:
        name: Company

      MigrationColumns:
        - sourceColumn:
            name: id
          destinationColumn:
            name: id
            options:
              type_cast: uuid

        - sourceColumn:
            name: name
          destinationColumn:
            name: NAME
            options:
              type_cast: varchar

        - sourceColumn:
            name: created
          destinationColumn:
            name: CREATED
            options:    
              type_cast: datetime
        - sourceColumn:
            name: email
          destinationColumn:
            name: EMAIL
            options:     
              type_cast: string
        - sourceColumn:
            name: updated
          destinationColumn:
            name: UPDATED
            options:
              type_cast: datetime
         - sourceColumn:
            name: code
          destinationColumn:
            name: CODE
            options:      
              type_cast: string


yaml 파일 선언이 완료되면 다음 명령을 실행합니다.
madmigrate -f schema.yaml
또는 마이그레이션 논리를 여러 .yaml 또는 .json 파일로 분리할 수 있습니다. 중요한 것은 하나의 기본.yaml 파일이 있어야 하고 다른 파일을 이 기본 파일로 가져와야 한다는 것입니다.
main.yaml 파일:

version: 1.1
Configs:
  - SourceConfig:
      dbURI: "mysql://root:[email protected]/old"
  - DestinationConfig:
      dbURI: "postgresql://root:[email protected]/new"

migrationTables:
  - migrationTable: !import company.yaml
  - migrationTable: !import op_cond.json


company.yaml 파일

SourceTable:
  name: company
DestinationTable:
  name: company
  create: true 

MigrationColumns:
  - sourceColumn:
      name: id
    destinationColumn: 
      name: id
      options:
        primary_key: true
        type_cast: uuid

  - sourceColumn:
      name: name
    destinationColumn:
      name: name
      options:
        length: 120
        type_cast: varchar
        nullable: false

  - sourceColumn:
      name: created
    destinationColumn:
      name: created
      options:
        type_cast: datetime
  - sourceColumn:
      name: updated
    destinationColumn:
      name: updated
      options:
        type_cast: datetime
        nullable: true

op_conds.json 파일

{
    "SourceTable": {
      "name": "operation_conditions"
    },
    "DestinationTable": {
      "name": "operation_conditions",
      "create": true
    },
    "MigrationColumns": [
      {
        "sourceColumn": {
          "name": "id"
        },
        "destinationColumn": {
          "name": "id",
          "options": {
            "primary_key": true,
            "type_cast": "uuid"
          }
        }
      },
      {
        "sourceColumn": {
          "name": "interest"
        },
        "destinationColumn": {
          "name": "interest",
          "options": {
            "type_cast": "varchar",
            "length": 30,
            "nullable": false
          }
        }
      },
      {
        "sourceColumn": {
          "name": "FIFD"
        },
        "destinationColumn": {
          "name": "FIFD",
          "options": {
            "type_cast": "varchar",
            "length": 30,
            "nullable": false
          }
        }
      },
      {
        "sourceColumn": {
          "name": "comission"
        },
        "destinationColumn": {
          "name": "comission",
          "options": {
            "type_cast": "varchar",
            "length": 30,
            "nullable": false
          }
        }
      }
    ]
  }


현재 SQLNOSQL 의 모든 기능이 완전히 구현되지 않았으므로 계속해서 새로운 기능을 개발하고 추가하고 있습니다.
이 도구를 구현하기 위해 우리team에게 놀라운 일을 해주셔서 감사합니다.

좋은 웹페이지 즐겨찾기