Knex: ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ๋‚ด๋ถ€์˜ ์—ด์—์„œ null ํ—ˆ์šฉ ์ œ์•ฝ ์กฐ๊ฑด์„ ๋ณ€๊ฒฝํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

์— ๋งŒ๋“  2016๋…„ 02์›” 22์ผ  ยท  10์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: knex/knex

์—ด์— ๋Œ€ํ•œ ์ œ์•ฝ ์กฐ๊ฑด์„ ๋ณ€๊ฒฝํ•˜๋ ค๊ณ  ํ•˜์ง€๋งŒ ์—ด์„ ๋‹ค์‹œ ๋งŒ๋“ค๋ ค๊ณ  ํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ด๊ณ  ์‹คํŒจํ•ฉ๋‹ˆ๋‹ค.

exports.up = function(knex, Promise) {  
  return knex.schema.table("images", function(table) {
    table.string("checksum").notNullable();
  });
};

exports.down = function(knex, Promise) {
  return knex.schema.table("images", function(table) {
    table.string("checksum").nullable();
  });
};
PR please feature request schema

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

Google์—์„œ ์—ฌ๊ธฐ๋กœ ์˜ค๋Š” ์‚ฌ๋žŒ๋“ค์„ ์œ„ํ•ด ๊ตฌ๋ฌธ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

Nullable์ด ์•„๋‹Œ ๊ธฐ์กด ์—ด์„ nullable๋กœ ๋ณ€ํ™˜(Nullable์ด ์•„๋‹Œ ๊ฒƒ์„ nullable๋กœ ์„ค์ •ํ•˜๋ ค๋ฉด ์œ„/์•„๋ž˜๋ฅผ ๋ฐ˜๋Œ€๋กœ).

exports.up = knex => {
  return knex.schema
    .alterTable('images', (table) => {
      table.string('checksum').nullable().alter();
    });
};

exports.down = knex => {
  return knex.schema
    .alterTable('images', table => {
      table.string('checksum').notNullable().alter();
    });
};

๋ชจ๋“  10 ๋Œ“๊ธ€

@Rush ์ €๋Š” .nullable() ๋ฐ .notNullable() ๊ฐ€ ์ด๊ฒƒ์„ ์œ„ํ•ด ์‚ฌ์šฉ๋˜์–ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ๋‹น์‹ ์ด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒƒ์„ ์‹คํ–‰ํ•˜๊ณ  ์‹ถ์–ดํ•˜๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

ALTER TABLE tableName ALTER COLUMN columnName DROP NOT NULL
ALTER TABLE tableName ALTER COLUMN columnName SET NOT NULL

๊ทธ๋ฆฌ๊ณ  ํ˜„์žฌ .raw ์™ธ์—๋Š” API์—์„œ ์ด๊ฒƒ์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์„ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

@rhys-vdw ์ด์— ๋Œ€ํ•ด ์–ด๋–ป๊ฒŒ ์ƒ๊ฐํ•˜์‹ญ๋‹ˆ๊นŒ? .dropNotNull() / .setNotNull() ๋˜๋Š” ์ด์™€ ์œ ์‚ฌํ•œ ๊ฒƒ์ด schemaBuilder์— ์ถ”๊ฐ€ํ•  ๊ฐ€์น˜๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ? .dropForeign() ์˜ ๊ตฌํ˜„๊ณผ ๋งค์šฐ ์œ ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

.dropNotNull()/.setNotNull() ๋˜๋Š” ์ด์™€ ์œ ์‚ฌํ•œ ๊ฒƒ์ด schemaBuilder์— ์ถ”๊ฐ€ํ•  ๊ฐ€์น˜๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ?

์˜ˆ, ํ•˜์ง€๋งŒ ์•„๋งˆ๋„ .dropNullable(...columnNames) ๋ฐ .setNullable(...columnNames) ์ž…๋‹ˆ๋‹ค.

@rhys-vdw ๋‹ค์‹œ ์ƒ๊ฐํ•ด๋ณด๋ฉด ์ด๊ฒƒ์ด postgres ์ด์™ธ์˜ ๋‹ค๋ฅธ ๋ฐฉ์–ธ์—๋Š” ๋„ˆ๋ฌด ๋ถˆํŽธํ•  ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๊ฐœ์ธ์ ์œผ๋กœ ๋‚˜๋Š” ๋‹ค์Œ์— ๋Œ€ํ•œ ์ข‹์€ ํ•ด๊ฒฐ์ฑ…์ด ์—†๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

Postgres dropNullable: ALTER TABLE table ALTER COLUMN columnName DROP NOT NULL
Postgres setNullable: ALTER TABLE table ALTER COLUMN columnName SET NOT NULL

MSSQL dropNullable: ALTER TABLE table ALTER COLUMN columnName columnType NULL
MSSQL setNullable: ALTER TABLE table ALTER COLUMN columnName columnType NOT NULL

MySQL/Maria/Oracle dropNullable: ALTER TABLE table MODIFY columnName columnType NULL;
MySQL/Maria/Oracle setNullable: ALTER TABLE table MODIFY columnName columnType NOT NULL;

Sqlite: No support?

์‹คํ–‰ ์ค‘์ธ ๋ฐฉ์–ธ์— ๋”ฐ๋ผ ์ผ๊ด€๋˜์ง€ ์•Š์€ ์ธ์ˆ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. Postgres๋Š” ์ด๋ฆ„๋งŒ ์›ํ•˜๋Š” ๋ฐ˜๋ฉด ๋‹ค๋ฅธ Postgres๋Š” ์ด๋ฆ„ + ๋ฐ์ดํ„ฐ ์œ ํ˜•(+ ๊ธฐ๋ณธ๊ฐ’?)์„ ์›ํ•ฉ๋‹ˆ๋‹ค.

๊ฐ€์น˜๊ฐ€ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์‹ญ๋‹ˆ๊นŒ?

์šฐ๋ฆฌ๋Š” SQLite์™€ Postgres๋ฅผ ๋ชจ๋‘ ์ง€์›ํ–ˆ์ง€๋งŒ SQLite๋Š” ๋„ˆ๋ฌด ๋‹ฌ๋ผ์„œ ์–ด๋–ค ์ถ”์ƒํ™”๋กœ๋„ ์ˆจ๊ธธ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค... ๋”ฐ๋ผ์„œ ์˜ˆ์™ธ๋ฅผ ๋˜์ง€๋Š” ๊ฒƒ์€ ์•„๋งˆ๋„ ๊ทธ๋Ÿฐ ๊ฒฝ์šฐ์— ์˜ณ์€ ์ผ์ž…๋‹ˆ๋‹ค. Rails์˜ ActiveRecord ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์€ ์ œ์•ฝ ์กฐ๊ฑด ๋ณ€๊ฒฝ์„ ์ง€์›ํ•˜๋ฏ€๋กœ ์˜๊ฐ์„ ์–ป์„ ์ˆ˜ ์žˆ๋Š” ๊ณณ์ด ์•„๋‹๊นŒ์š”?

์ด๊ฒƒ์€ ๊ฒฐ๊ตญ ๊ตฌํ˜„ ๊ฐ€๋Šฅํ–ˆ์Šต๋‹ˆ๋‹ค. PR์„ ํ–ˆ์Šต๋‹ˆ๋‹ค.

+1 -- ์ €๋„ ๋ฐฉ๊ธˆ ์ด ๋ฌธ์ œ๋ฅผ ์ ‘ํ–ˆ๋Š”๋ฐ ์ผ์ข…์˜ ์ฐจ๋‹จ ์žฅ์น˜์ž…๋‹ˆ๋‹ค. nullable์ด ์•„๋‹Œ ์—ด์— ๋Œ€ํ•œ ํ‘œํ˜„์„ ๋งคํ•‘ํ•˜๋Š” ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์„ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•  ๋•Œ๋งˆ๋‹ค ์ด๊ฒƒ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

@morungos ๋Š” ์‹ค์ œ๋กœ ์ฐจ๋‹จ๊ธฐ๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. knex์— ๋Œ€ํ•ด ํŠน์ˆ˜ API๊ฐ€ ์—†๋Š” ํ•ญ๋ชฉ(๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์„ ์ž‘์„ฑํ•  ๋•Œ ๋งŽ์€ ํ•ญ๋ชฉ)์— ๋Œ€ํ•ด ํ•ญ์ƒ knex.raw์— ๋“œ๋กญํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

์ด pull ์š”์ฒญ์ด ์™„๋ฃŒ๋˜๋ฉด ์ด ๋ฌธ์ œ๋ฅผ ๋‹ซ์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. https://github.com/tgrisser/knex/pull/1759

๋„ค, ์ €๋Š” .raw๋ฅผ ๋ช‡ ๋ฒˆ ์‚ฌ์šฉํ–ˆ์ง€๋งŒ ์ „์ฒด ๋ฌธ์žฅ์œผ๋กœ ๋ฐ”๋€Œ๋ฉด ๋ฌด๋ฆŽ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์˜ ์ „์ฒด ์‚ฌ์šฉ์— ์˜๋ฌธ์„ ๊ฐ–๊ธฐ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. ๊ฒฐ๊ตญ์—๋Š” ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค. null์ด ์•„๋‹Œ ์ด์ƒํ•œ ๊ฐ’์„ ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ์„ค์ •ํ•œ ๋‹ค์Œ ๋งคํ•‘ ๊ทœ์น™์„ ์ ์šฉํ•˜์—ฌ ๊ฐ’์„ ์—…๋ฐ์ดํŠธํ•œ ๋‹ค์Œ ์›๋ณธ์„ ์‚ญ์ œํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ํŠนํžˆ MySQL์—์„œ ๋ฌด๊ฒฐ์„ฑ์„ ๊ฐ•ํ™”ํ•˜๊ณ  ์ค‘๊ฐ„ ๋‹จ๊ณ„์—์„œ๋„ ๋ฌด๊ฒฐ์„ฑ์„ ์š”๊ตฌํ•˜๋Š” ๋‚˜์œ ์Šต๊ด€์ด๋ผ๋ฉด ๊ทธ๋ ‡๊ฒŒ ํ•˜๊ธฐ๊ฐ€ ์–ด๋ ค์šธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Google์—์„œ ์—ฌ๊ธฐ๋กœ ์˜ค๋Š” ์‚ฌ๋žŒ๋“ค์„ ์œ„ํ•ด ๊ตฌ๋ฌธ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

Nullable์ด ์•„๋‹Œ ๊ธฐ์กด ์—ด์„ nullable๋กœ ๋ณ€ํ™˜(Nullable์ด ์•„๋‹Œ ๊ฒƒ์„ nullable๋กœ ์„ค์ •ํ•˜๋ ค๋ฉด ์œ„/์•„๋ž˜๋ฅผ ๋ฐ˜๋Œ€๋กœ).

exports.up = knex => {
  return knex.schema
    .alterTable('images', (table) => {
      table.string('checksum').nullable().alter();
    });
};

exports.down = knex => {
  return knex.schema
    .alterTable('images', table => {
      table.string('checksum').notNullable().alter();
    });
};

์ฐธ๊ณ ๋กœ nullable ๋ฅผ nonNullable ๋กœ ๋ณ€๊ฒฝํ•˜๋ ค๋Š” ๊ฒฝ์šฐ ๋จผ์ € ํ•ด๋‹น ์—ด์„ ๋ฌด์–ธ๊ฐ€๋กœ ์ฑ„์›Œ์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

Google์—์„œ ์—ฌ๊ธฐ๋กœ ์˜ค๋Š” ์‚ฌ๋žŒ๋“ค์„ ์œ„ํ•ด ๊ตฌ๋ฌธ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

Nullable์ด ์•„๋‹Œ ๊ธฐ์กด ์—ด์„ nullable๋กœ ๋ณ€ํ™˜(Nullable์ด ์•„๋‹Œ ๊ฒƒ์„ nullable๋กœ ์„ค์ •ํ•˜๋ ค๋ฉด ์œ„/์•„๋ž˜๋ฅผ ๋ฐ˜๋Œ€๋กœ).

exports.up = knex => {
  return knex.schema
    .alterTable('images', (table) => {
      table.string('checksum').nullable().alter();
    });
};

exports.down = knex => {
  return knex.schema
    .alterTable('images', table => {
      table.string('checksum').notNullable().alter();
    });
};
์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰