마이그레이션¶
소스코드 변경사항 관리를 위해 git/svn을 사용하는 것처럼, 데이터베이스의 변경사항을 추적하기 위해 마이그레이션을 사용할 수 있습니다. 마이그레이션을 통해 기존 데이터베이스를 다른 상태로 또는 그 반대로 전송할 수 있습니다. 이러한 상태 전환은 마이그레이션 파일에 저장됩니다. 마이그레이션 파일은 새 상태로 이동하는 방법과 이전 상태로 돌아 가기 위해 변경 사항을 되 돌리는 방법을 설명합니다.
Sequelize CLI가 필요합니다. CLI는 마이그레이션과 프로젝트 부트스트랩 지원을 제공합니다.
The CLI¶
CLI 설치¶
CLI 설치부터 시작하겠습니다. 여기서 지침을 찾을 수 있습니다. 가장 선호되는 방법은 다음과 같이 로컬로 설치하는 것입니다
$ npm install --save sequelize-cli
부트스트랩핑¶
빈 프로젝트를 생성하기 위해 init 명령어를 사용할 수 있습니다.
$ npx sequelize-cli init
이것은 다음과 같은 폴더를 생성합니다.
config, CLI에 데이터베이스 연결 방법을 알려주는 설정 파일 포함models, 프로젝트를 위한 모든 모델 파일들 포함migrations, 모든 마이그레이션 파일들 포함seeders, 모든 시드 파일들 포함
설정¶
계속 진행하기 전에 CLI에 데이터베이스 연결 방법을 알려야합니다. 이를 위해 설정 구성 파일 config/config.json을 엽니다. 설정파일은 다음과 같습니다.
{
"development": {
"username": "root",
"password": null,
"database": "database_development",
"host": "127.0.0.1",
"dialect": "mysql"
},
"test": {
"username": "root",
"password": null,
"database": "database_test",
"host": "127.0.0.1",
"dialect": "mysql"
},
"production": {
"username": "root",
"password": null,
"database": "database_production",
"host": "127.0.0.1",
"dialect": "mysql"
}
}
이제이 파일을 편집하고 올바른 데이터베이스 정보 및 방언(dialect)을 설정하십시오. 객체의 키 (예 : “development”)는 model.index.js에서 process.env.NODE_ENV와 일치시키기 위해 사용됩니다 (정의되지 않은 경우 “development”가 기본값).
참고 : 데이터베이스가 아직 없으면 db:create 명령을 호출하면됩니다. 적절한 액세스 권한이 있으면 해당 데이터베이스가 작성됩니다.
첫 번쨰 모델 생성(그리고 마이그레이션)¶
CLI 설정파일을 올바르게 구성했으면 첫 번째 마이그레이션을 작성할 준비가되었습니다. 이것은 매우 간단한 명령어로 실행하 수 있습니다.
model:generate 명령어를 사용할 것 입니다. 두 가지 옵션을 반드시 포함해야 합니다.
name, 모델의 이름attributes, 모델의 속성 리스트
User 모델을 생성해봅시다.
$ npx sequelize-cli model:generate --name User --attributes firstName:string,lastName:string,email:string
이것은 다음을 따릅니다.
models디렉터리(폴더)에user파일을 생성합니다.migrations디렉터리(폴더)에XXXXXXXXXXXXXX-create-user.js와 같은 이름을 가진 파일을 생성합니다.
참고: Sequelize는 모델 파일 만 사용하며 테이블 표현입니다. 반면, 마이그레이션 파일은 CLI에서 사용되는 해당 모델 또는 보다 구체적으로 해당 테이블의 변경입니다. 데이터베이스의 일부 변경에 대한 커밋 또는 로그처럼 마이그레이션을 처리하십시오.
마이그레이션 동작¶
이 단계까지는 데이터베이스에 아무것도 삽입하지 않았습니다. 첫 번째 모델 사용자에 필요한 모델 및 마이그레이션 파일을 만들었습니다. 이제 데이터베이스에서 해당 테이블을 실제로 만들려면 db:migrate 명령을 실행해야합니다.
$ npx sequelize-cli db:migrate
이것은 다음 스탭을 실행합니다.
데이터베이스에서
SequelizeMeta로 불리는 테이블을 안전하게 합니다. 이 테이블은 현재 데이터베이스에서 실행 된 마이그레이션을 기록하는 데 사용됩니다.아직 실행되지 않은 마이그레이션 파일을 찾기 시작하십시오.
SequelizeMeta테이블을 확인하면 가능합니다. 이 경우 마지막 단계에서 생성한XXXXXXXXXXXXXX-create-user.js마이그레이션을 실행합니다.마이그레이션 파일에 지정된대로 모든 열이있는
Users라는 테이블을 작성합니다.
마이그레이션 취소¶
이제 테이블이 생성되어 데이터베이스에 저장되었습니다. 마이그레이션을 사용하면 명령을 실행하여 이전 상태로 되돌릴 수 있습니다.
가장 최근의 마이그레이션을 되돌리기 위해 dv:migrate:undo를 사용할 수 있습니다.
$ npx sequelize-cli db:migrate:undo
db:migrate:undo:all 명령으로 모든 마이그레이션을 실행 취소하여 초기 상태로 되돌릴 수 있습니다. --to 옵션에 이름을 전달하여 특정 마이그레이션으로 되돌릴 수도 있습니다.
$ npx sequelize-cli db:migrate:undo:all --to XXXXXXXXXXXXXX-create-posts.js
첫 번째 피드 생성¶
일부 데이터를 몇 개의 테이블에 삽입하려고한다고 가정합니다. 이전 예제를 따라 가면 User 테이블에 대한 데모 사용자를 만들 수 있습니다.
모든 데이터 마이그레이션을 관리하기 위해 파종기(씨앗뿌리기)를 사용할 수 있습니다. 시드 파일은 데이터베이스 테이블을 샘플 데이터 또는 테스트 데이터로 채우는 데 사용할 수있는 일부 데이터 변경입니다.
User 테이블에 데모 사용자를 추가 할 seed 파일을 만들어 봅시다.
$ npx sequelize-cli seed:generate --name demo-user
이 명령어는 seeder 디렉터리(폴더)에 씨드 파일을 생성합니다. 파일 이름은 XXXXXXXXXXXXXX-demo-user.js와 같습니다. 마이그레이션 파일과 동일한 up/down 시맨틱을 따릅니다.
이제이 파일을 편집하여 데모 사용자를 사용자 테이블에 삽입해야합니다.
'use strict';
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.bulkInsert('Users', [{
firstName: 'John',
lastName: 'Doe',
email: 'demo@demo.com',
createdAt: new Date(),
updatedAt: new Date()
}], {});
},
down: (queryInterface, Sequelize) => {
return queryInterface.bulkDelete('Users', null, {});
}
};
씨드 실행¶
마지막 스탭에서 씨드를 생성했습니다. 여전히 데이터베이스에 커밋되지 않았습니다. 커밋을 위해 간단한 명령을 실행해야합니다.
$ npx sequelize-cli db:seed:all
이것은 씨드파일을 실행하고 User 테이블에 데모 유저 데이터를 추가합니다.
참고: 시더 실행은 SequelizeMeta 테이블을 사용하는 마이그레이션과 달리 어디에도 저장되지 않습니다. 이것을 무시하려면 저장 섹션을 읽으십시오
씨드 취소¶
시더는 스토리지를 사용하는 경우 취소 할 수 있습니다. 사용할 수있는 두 가지 명령이 있습니다.
가장 최신의 시드를 취소하고 싶다면
$ npx sequelize-cli db:seed:undo
특정 요소의 시드를 취소하고 싶다면
$ npx sequelize-cli db:seed:undo --seed name-of-seed-as-in-data
모든 시드를 취소하고 싶다면
$ npx sequelize-cli db:seed:undo:all
Advance Topics¶
마이그레이션 스켈레톤¶
다음 스켈레톤은 일반적인 마이그레이션 파일을 보여줍니다.
module.exports = {
up: (queryInterface, Sequelize) => {
// logic for transforming into the new state
},
down: (queryInterface, Sequelize) => {
// logic for reverting the changes
}
}
migration:generate를 사용하여이 파일을 생성 할 수 있습니다. 마이그레이션 디렉터리(폴더)에 xxx-migration-skeleton.js 파일을 생성합니다.
$ npx sequelize-cli migration:generate --name migration-skeleton
전달 된 queryInterface 오브젝트를 사용하여 데이터베이스를 수정할 수 있습니다. Sequelize는 STRING 또는 INTEGER와 같이 사용가능한 데이터 타입을 저장합니다. up 또는 down 함수는 Promise를 반환합니다. 예제를 살펴 보십쇼.
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.createTable('Person', {
name: Sequelize.STRING,
isBetaMember: {
type: Sequelize.BOOLEAN,
defaultValue: false,
allowNull: false
}
});
},
down: (queryInterface, Sequelize) => {
return queryInterface.dropTable('Person');
}
}
다음은 트랜잭션을 사용하여 데이터베이스에서 두 가지 변경을 수행하여 실패시 모든 명령이 성공적으로 실행 또는 롤백되도록하는 마이그레이션의 예입니다.
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.sequelize.transaction((t) => {
return Promise.all([
queryInterface.addColumn('Person', 'petName', {
type: Sequelize.STRING
}, { transaction: t }),
queryInterface.addColumn('Person', 'favoriteColor', {
type: Sequelize.STRING,
}, { transaction: t })
])
})
},
down: (queryInterface, Sequelize) => {
return queryInterface.sequelize.transaction((t) => {
return Promise.all([
queryInterface.removeColumn('Person', 'petName', { transaction: t }),
queryInterface.removeColumn('Person', 'favoriteColor', { transaction: t })
])
})
}
};
외래키를 가지고 있는 마이그레이션의 다음예입니다. 참조를 사용하여 외래키를 지정할 수 있습니다.
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.createTable('Person', {
name: Sequelize.STRING,
isBetaMember: {
type: Sequelize.BOOLEAN,
defaultValue: false,
allowNull: false
},
userId: {
type: Sequelize.INTEGER,
references: {
model: {
tableName: 'users',
schema: 'schema'
}
key: 'id'
},
allowNull: false
},
});
},
down: (queryInterface, Sequelize) => {
return queryInterface.dropTable('Person');
}
}
다음은 async / await를 사용하여 새 열에 고유 인덱스를 생성하는 마이그레이션의 예입니다.
module.exports = {
async up(queryInterface, Sequelize) {
const transaction = await queryInterface.sequelize.transaction();
try {
await queryInterface.addColumn(
'Person',
'petName',
{
type: Sequelize.STRING,
},
{ transaction }
);
await queryInterface.addIndex(
'Person',
'petName',
{
fields: 'petName',
unique: true,
},
{ transaction }
);
await transaction.commit();
} catch (err) {
await transaction.rollback();
throw err;
}
},
async down(queryInterface, Sequelize) {
const transaction = await queryInterface.sequelize.transaction();
try {
await queryInterface.removeColumn('Person', 'petName', { transaction });
await transaction.commit();
} catch (err) {
await transaction.rollback();
throw err;
}
},
};
.sequelizerc 파일¶
이것은 특수 설정 파일입니다. 일반적으로 CLI에 인수로 전달할 다음 옵션을 지정할 수 있습니다.
env: 명령을 실행할 환경config: 설정파일 경로options-path: 추가 옵션이있는 JSON 파일의 경로migrations-path: 마이그레이션 디렉터리(폴더) 경로seeders-path: seeder 디렉터리(폴더) 경로models-path: models 디렉터리(폴더) 경로url: 사용할 데이터베이스 연결 문자열입니다. –config 파일 사용의 대안debug: 사용 가능한 경우 다양한 디버그 정보 표시
사용할 수있는 일부 시나리오.
migrations,models,seeders또는config디렉터리(폴더) 기본경로 재정의를 원할 때config.json의 이름을database.json과 같은 다른 이름으로 바꾸고 싶을 때
그리고 훨씬 더. 이 파일을 사용자 정의 구성에 사용하는 방법을 살펴 보겠습니다.
우선, 프로젝트의 루트 디렉토리에 빈 파일을 만들어 봅시다.
const path = require('path');
module.exports = {
'config': path.resolve('config', 'database.json'),
'models-path': path.resolve('db', 'models'),
'seeders-path': path.resolve('db', 'seeders'),
'migrations-path': path.resolve('db', 'migrations')
}
이 구성을 사용하면 CLI에
설정 구성을 위한
config/database.json사용db/models를 모델 폴더로 사용db/seeders를 모델 폴더로 사용db/migrations를 모델 폴더로 사용
동적 설정¶
설정 파일은 기본적으로 config.json이라는 JSON 파일입니다. 그러나 때로는 JSON 파일에서는 불가능한 일부 코드를 실행하거나 환경 변수에 액세스하려고합니다.
Sequelize CLI는 JSON과 JS 파일에서 읽을 수 있습니다. 이것은 .sequelizerc 파일과 함께 설정하 수 있습니다.
첫 번째로 프로젝트 루트 경로에 .sequelizerc 파일을 생성합니다. 이 파일은 JS 파일의 구성 경로를 대체해야합니다.
const path = require('path');
module.exports = {
'config': path.resolve('config', 'config.js')
}
Sequelize CLI는 설정 옵션을 가져오기 위해 config/config.js를 읽을 수 있습니다. 이 파일은 JS 파일이므로 모든 코드를 실행하고 최종 동적 구성 파일을 내보낼 수 있습니다.
예시 config/config.js파일
const fs = require('fs');
module.exports = {
development: {
username: 'database_dev',
password: 'database_dev',
database: 'database_dev',
host: '127.0.0.1',
dialect: 'mysql'
},
test: {
username: 'database_test',
password: null,
database: 'database_test',
host: '127.0.0.1',
dialect: 'mysql'
},
production: {
username: process.env.DB_USERNAME,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME,
host: process.env.DB_HOSTNAME,
dialect: 'mysql',
dialectOptions: {
ssl: {
ca: fs.readFileSync(__dirname + '/mysql-ca-master.crt')
}
}
}
};
바벨 사용¶
이제 .sequelizerc 파일 사용법을 알았습니다. 이제 설정에서 babel을 사용하기 위해이 파일을 사용하는 방법을 살펴 보겠습니다. 이를 통해 ES6/ES7 구문으로 마이그레이션 및 시드를 작성할 수 있습니다.
첫 번째로 babel-register를 설치합니다.
$ npm i --save-dev babel-register
.sequelizerc 파일을 실행해라. 여기에는 sequelize-cli를 위해 변경하려는 구성이 포함될 수 있지만 코드베이스에 babel을 등록하기를 원합니다.
$ touch .sequelizerc # Create rc file
이 파일에 babel-register 추가하라
require("babel-register");
const path = require('path');
module.exports = {
'config': path.resolve('config', 'config.json'),
'models-path': path.resolve('models'),
'seeders-path': path.resolve('seeders'),
'migrations-path': path.resolve('migrations')
}
이제 CLI는 마이그레이션/시더 등에서 ES6/ES7 코드를 실행할 수 있습니다. 이는 .babelrc 구성에 따라 다릅니다. babeljs.io에서 자세한 내용을 읽으십시오.
환경 변수 사용¶
CLI를 사용하여 config/config.js에 있는 환경 변수를 직접적으로 접근할 수 있습니다. .sequelizerc를 사용하여 구성에 config/config.js를 사용하도록 CLI에 지시 할 수 있습니다. 이 것은 마지막 세션에서 설명합니다.
환경 변수 속성을 노출할 수 있습니다.
module.exports = {
development: {
username: 'database_dev',
password: 'database_dev',
database: 'database_dev',
host: '127.0.0.1',
dialect: 'mysql'
},
test: {
username: process.env.CI_DB_USERNAME,
password: process.env.CI_DB_PASSWORD,
database: process.env.CI_DB_NAME,
host: '127.0.0.1',
dialect: 'mysql'
},
production: {
username: process.env.PROD_DB_USERNAME,
password: process.env.PROD_DB_PASSWORD,
database: process.env.PROD_DB_NAME,
host: process.env.PROD_DB_HOSTNAME,
dialect: 'mysql'
}
};
dialect 옵션 선택¶
dialectOption을 지정하고 싶을 때, 일반적인 설정이라면 config/config.json에 추가하면됩니다. 때로는 dialectOptions를 얻기 위해 일부 코드를 실행하려는 경우 이러한 경우 동적 구성 파일을 사용해야합니다.
{
"production": {
"dialect":"mysql",
"dialectOptions": {
"bigNumberStrings": true
}
}
}
프로덕션 사용¶
프로덕션 환경에서 CLI 및 마이그레이션 설정 사용에 대한 팁.
구성 설정에 환경 변수를 사용합니다. 이것은 동적구성으로 더 좋은 수행결과를 얻습니다. 샘플 프로덕션 안전 구성은 다음과 같습니다.
const fs = require('fs');
module.exports = {
development: {
username: 'database_dev',
password: 'database_dev',
database: 'database_dev',
host: '127.0.0.1',
dialect: 'mysql'
},
test: {
username: 'database_test',
password: null,
database: 'database_test',
host: '127.0.0.1',
dialect: 'mysql'
},
production: {
username: process.env.DB_USERNAME,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME,
host: process.env.DB_HOSTNAME,
dialect: 'mysql',
dialectOptions: {
ssl: {
ca: fs.readFileSync(__dirname + '/mysql-ca-master.crt')
}
}
}
};
우리의 목표는 다양한 데이터베이스 비밀에 환경 변수를 사용하고 실수로 소스 제어에 체크인하지 않는 것입니다.
저장소¶
사용할 수있는 세 가지 유형의 저장소가 있습니다: sequelize, json 그리고 none.
sequelize: sequelize 데이터베이스의 테이블에 마이그레이션 및 시드를 저장합니다.json: json 파일에 마이그레이션 및 시드 저장none: 마이그레이션/시드를 저장하지 않습니다
마이그레이션 저장소¶
기본적으로 CLI는 실행 된 각 마이그레이션에 대한 항목을 포함하는 SequelizeMeta라는 테이블을 데이터베이스에 작성합니다. 이 동작을 변경하기 위해 구성 파일에 추가 할 수있는 세 가지 옵션이 있습니다. migrationStorage를 사용하여 마이그레이션에 사용할 스토리지 유형을 선택할 수 있습니다. json을 선택하면 migrationStoragePath를 사용하여 파일의 경로를 지정할 수 있습니다. 그렇지 않으면 CLI가 파일 sequelize-meta.json에 씁니다. sequelize를 사용하여 데이터베이스에 정보를 유지하지만 다른 테이블을 사용하려는 경우 migrationStorageTableName을 사용하여 테이블 이름을 변경할 수 있습니다. 또한 migrationStorageTableSchema 속성을 제공하여 SequelizeMeta 테이블에 대해 다른 스키마를 정의 할 수 있습니다.
{
"development": {
"username": "root",
"password": null,
"database": "database_development",
"host": "127.0.0.1",
"dialect": "mysql",
// Use a different storage type. Default: sequelize
"migrationStorage": "json",
// Use a different file name. Default: sequelize-meta.json
"migrationStoragePath": "sequelizeMeta.json",
// Use a different table name. Default: SequelizeMeta
"migrationStorageTableName": "sequelize_meta",
// Use a different schema for the SequelizeMeta table
"migrationStorageTableSchema": "custom_schema"
}
}
참고: nonce 저장소는 추천하지 않습니다. 이를 사용하기로 결정한 경우 마이그레이션이 수행하거나 수행하지 않은 작업에 대한 기록이 없다는 의미에 유의하십시오.
시드 저장소¶
기본적으로 CLI는 실행 된 시드를 저장하지 않습니다. 이 동작을 변경하기로 선택한 경우 구성 파일에서 seederStorage를 사용하여 스토리지 타입을 변경할 수 있습니다. json을 선택하면 seederStoragePath를 사용하여 파일 경로를 지정하거나 CLI가 sequelize-data.json 파일에 기록합니다. sequelize를 사용하여 데이터베이스에 정보를 유지하려는 경우 seederStorageTableName을 사용하여 테이블 이름을 지정하거나 기본적으로 SequelizeData가 됩니다.
{
"development": {
"username": "root",
"password": null,
"database": "database_development",
"host": "127.0.0.1",
"dialect": "mysql",
// Use a different storage. Default: none
"seederStorage": "json",
// Use a different file name. Default: sequelize-data.json
"seederStoragePath": "sequelizeData.json",
// Use a different table name. Default: SequelizeData
"seederStorageTableName": "sequelize_data"
}
}
연결정보 문자열¶
데이터베이스를 정의하는 구성 파일이있는 --config 옵션의 대안으로 --url 옵션을 사용하여 연결 문자열을 전달할 수 있습니다. 예를 들면 다음과 같습니다.
$ npx sequelize-cli db:migrate --url 'mysql://root:password@mysql_host.com/database_name'
dialect 별 옵션 전달¶
{
"production": {
"dialect":"postgres",
"dialectOptions": {
// dialect options like SSL etc here
}
}
}
프로그래밍 방식의 사용¶
sequelize는 프로그래밍 방식으로 실행 후 처리, 마이그레이션 작업을 로깅하기 위해 sister library을 가지고 있습니다.
쿼리 인터페이스¶
데이터베이스 스키마 변경하기 전에 설명된 queryInterface 객체를 사용하세요. 공개된 메소드의 전체 목록을 보려면 CheckInterface API 검사를 지원합니다.