Knex: ํ•œ ๋ฒˆ์— ์—ฌ๋Ÿฌ ์ฟผ๋ฆฌ๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

์— ๋งŒ๋“  2014๋…„ 04์›” 29์ผ  ยท  40์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: knex/knex

';'๋กœ ๊ตฌ๋ถ„๋œ ์—ฌ๋Ÿฌ ์ฟผ๋ฆฌ๋ฅผ ์‹คํ–‰ํ•˜๊ณ  ์‹ถ์€ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹จ์ผ ์ž„์›์— ์˜ํ•ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๊นŒ?

์‹คํŒจํ•œ ๋‚ด ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

      var query = '' +
        'UPDATE "records_raw" ' +
        'SET "title" = ? ' +
        'WHERE "id" = ?' +
        ';' +
        'UPDATE "records_raw" ' +
        'SET "title" = ? ' +
        'WHERE "id" = ?' +
        ';';

      var bindings = [
        "x", "1",
        "y", "2"
      ];

      knex.raw(query, bindings).exec(function(err, result) {
        assert.isNotError(err);
      });

์˜ค๋ฅ˜:

Error(cannot insert multiple commands into a prepared statement, ...

์ด๋Ÿฌํ•œ ์ฟผ๋ฆฌ์— ๋Œ€ํ•ด ์ค€๋น„๋œ ๋ช…๋ น๋ฌธ์„ ๋น„ํ™œ์„ฑํ™”ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๊นŒ?

feature request

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

๋ชจ๋“  ์—…๋ฐ์ดํŠธ ?
์ด์ œ multiQuery๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?
๊ทธ๋ ‡๋‹ค๋ฉด ์–ด๋–ค ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๊นŒ?

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

์•„๋‹ˆ์š”, ๋‘ ๋ฌธ์žฅ์œผ๋กœ ์‹คํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๊ธ€์Ž„, ์ด๊ฒƒ์€ ์•ฝ๊ฐ„ ์ œํ•œ์ ์ธ ์†”๋ฃจ์…˜์ž…๋‹ˆ๋‹ค

์ฟผ๋ฆฌ์—์„œ toString() ๋ฅผ ํ˜ธ์ถœํ•˜๊ณ  ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์‹ค์ œ๋กœ๋Š” ๊ถŒ์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

knex.raw(knex.raw(query, bindings) + '').exec(function(err, result) {
  assert.isNotError(err);
});

๊ธ€์Ž„, ๋‚˜๋Š” ๊ทธ๊ฒƒ์œผ๋กœ ๋ฌด์—‡์„ ํ•  ๊ฒƒ์ธ์ง€ ๋ณผ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ ์ค€๋น„๋œ ๋ช…๋ น๋ฌธ์„ ๋„๊ณ  ์ฟผ๋ฆฌ ๋ฌธ์ž์—ด๊ณผ ๋ฐ”์ธ๋”ฉ์„ ๊ฐ–๋Š” ๊ธฐ๋Šฅ์„ ์œ ์ง€ํ•˜๊ณ  ์‹ถ์ง€๋งŒ ๊ฐ€๋Šฅํ•œ์ง€ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค. ์ด์™€ ๊ด€๋ จ๋œ ๋ฌธ์„œ๋ฅผ ์ฐพ์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค.

์–ด์จŒ๋“ , ๋‚˜๋Š” ์‹œ๋„ํ–ˆ๋‹ค

knex.raw(query, bindings) + ''

๊ทธ๋Ÿฌ๋‚˜ ๊ทธ๊ฒƒ์€ ๋˜์กŒ์Šต๋‹ˆ๋‹ค - Object ๊ฐ์ฒด์—๋Š” 'clone'๋ฉ”์†Œ๋“œ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

0.6.0 ๋ธŒ๋žœ์น˜๋ฅผ ์‹œ๋„ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ๊ฑฐ๊ธฐ์—์„œ ์ž‘๋™ํ•  ๊ฒƒ์ด๋ผ๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋ช‡ ๊ฐ€์ง€ ํ…Œ์ŠคํŠธ๋ฅผ ๋งˆ์นœ ํ›„์— ๋ฆด๋ฆฌ์Šคํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋Ÿฐ๋ฐ ์™œ ๊ทธ๋Ÿฐ ๋‹จ์ผ ๋ฌธ์ž์—ด์„ ์‚ฌ์šฉํ•˜์—ฌ ๋‘ ๊ฐœ์˜ ์ฟผ๋ฆฌ ๋ฌธ์„ ์‹คํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๊นŒ? ํŒจํ‚ค์ง€๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ชฉ์ ์— ์–ด๊ธ‹๋‚˜์ง€ ์•Š์Šต๋‹ˆ๊นŒ?

๊ฐœ์ธ์ ์œผ๋กœ ํ•œ ๋ฒˆ์— ์—ฌ๋Ÿฌ ๊ฐœ์˜ INSERT ... ON DUPLICATE KEY UPDATE ๋ฅผ ๋งŒ๋“ค์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์—…๋ฐ์ดํŠธ๋œ ํ–‰๊ณผ ์ƒ์„ฑ๋œ ํ–‰(์˜ํ–ฅ์„ ๋ฐ›๋Š” ํ–‰ ๊ฐ’ ํ™•์ธ)์„ ์•Œ๊ณ  ์‹ถ๊ธฐ ๋•Œ๋ฌธ์— ์—ฌ๋Ÿฌ ๊ฐ’์œผ๋กœ ์‚ฝ์ž…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

์ €๋Š” Knex ์ œํ•œ ์‚ฌํ•ญ(๊ธฐ๋ณธ์ ์œผ๋กœ ๋Œ€๋ถ€๋ถ„์˜ ์‹œ๊ฐ„์— ์›์‹œ ์ฟผ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฐ๊ณผ)์„ ๋ฐœ๊ฒฌํ•œ ํ›„ node.js์— ๋Œ€ํ•œ ๋‹ค์–‘ํ•œ ์ฟผ๋ฆฌ ๋นŒ๋”๋ฅผ ์‚ฌ์šฉํ•ด ์™”์Šต๋‹ˆ๋‹ค. ๊ฒฐ๊ตญ ๋‚˜๋Š” SQL ๋นŒ๋”๋ฅผ ์ง์ ‘ ์ฝ”๋”ฉํ–ˆ์Šต๋‹ˆ๋‹ค - QSql Demo . ์™„์ „ํ•˜๊ฑฐ๋‚˜ ์ƒ์‚ฐ ์ค€๋น„๊ฐ€ ๋œ ๊ฒƒ์€ ์•„๋‹ˆ์ง€๋งŒ ๊ธฐ๋ณธ์ ์œผ๋กœ ๋‚ด๊ฐ€ ์ƒ๊ฐํ•˜๋Š” ๋ฐฉ์‹์„ ์š”์•ฝํ•ฉ๋‹ˆ๋‹ค.

์•„์ฃผ ๋ฉ‹์ง„ ๋ฐ๋ชจ์ž…๋‹ˆ๋‹ค. ๋‹ค์Œ ๋ฆด๋ฆฌ์Šค ์ดํ›„์— ๊ทธ๋Ÿฐ ๊ฒƒ์„ ์ถ”๊ฐ€ํ•  ๊ณ„ํš์ด์—ˆ์Šต๋‹ˆ๋‹ค. 0.6 ๋ธŒ๋žœ์น˜๋ฅผ ์‚ฌ์šฉํ•ด ๋ณด์…จ๋‚˜์š”?

QSQL์ด ๋ณด๋‹ค ๊ฐ•๋ ฅํ•œ ์ฟผ๋ฆฌ ๋นŒ๋”์˜ ํ•„์š”์„ฑ์„ ์ฑ„์šธ ์ˆ˜ ์žˆ๋Š” ๋ฐ˜๋ฉด Knex๋Š” ์„œ๋กœ ๋‹ค๋ฅธ ๋ฐฉ์–ธ ์‚ฌ์ด์˜ ์‚ฌ๋งˆ๊ท€์— ๋Œ€ํ•œ ์—ฐ๊ฒฐ ํ’€๋ง ๋ฐ ํ‰ํ™œํ™”๋ฅผ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ํ˜‘์—…์„ ์œ„ํ•œ ์—ฌ์ง€๊ฐ€ ์žˆ๋Š”์ง€ ๊ถ๊ธˆํ•ฉ๋‹ˆ๋‹ค.

์•„๋ฌดํŠผ ์ž˜๋ดค์Šต๋‹ˆ๋‹ค ์ž˜ ๋ณด๊ณ  ๊ฐ‘๋‹ˆ๋‹ค!

๊ธ€์Ž„์š”, ์šฐ๋ฆฌ๋Š” 0.6์„ ์‹œ๋„ํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ํ•œ ๊ณณ์—์„œ ๋งŽ์€ ์ฝ”๋“œ๊ฐ€ knex๋ฅผ ์‚ฌ์šฉํ•œ ๋‹ค์Œ ๋‹ค๋ฅธ ๊ณณ์—์„œ ์›์‹œ ์ฟผ๋ฆฌ๋ฅผ ์ˆ˜ํ–‰ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์•ฝ๊ฐ„์˜ ์กฐ์‚ฌ ํ›„์— ๋‚˜๋Š” ์ „์ฒด ์Šคํƒ์„ ์œ ์ง€ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๊ณ  ๊ธฐ๋Šฅ์„ ์ฆ‰์‹œ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์œผ๋กœ ๊ต์ฒดํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.

๊ธ€์Ž„์š”, ๋ถ„๋ช…ํžˆ ํ˜‘์—…์˜ ์—ฌ์ง€๊ฐ€ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์ง€๋งŒ ๋จผ์ € QSql์„ ์•ˆ์ •ํ™”ํ•˜๋Š” ๋ฐ ์‹œ๊ฐ„์ด ๊ฑธ๋ฆด ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‚ด ๋ง์€ 99% ์š”๊ตฌ ์‚ฌํ•ญ๊ณผ ์‚ฌ์šฉ ์‚ฌ๋ก€(์ผ๋ถ€ ๊ตฌ์„ฑ์€ ์—ฌ์ „ํžˆ โ€‹โ€‹์•ฝ๊ฐ„ ๋ชป์ƒ๊ธด ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋“ฏ์ด)์™€ ์ผ์น˜ํ•˜๋Š” ๋ฉ‹์ง„ API๋ฅผ ์ •์˜ํ•˜๊ณ  ๋‹ค๋ฅธ ๋ฐฑ์—”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋„๋ก ์ ์ ˆํ•œ ์ถ”์ƒํ™”๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ฟผ๋ฆฌ ๋ฐฐ์—ด์„ ์ „๋‹ฌํ•˜๊ณ  ๊ฒฐ๊ณผ๋„ ๋ฐฐ์—ด์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ์ด์™€ ๊ฐ™์ด ๊ฐ„๋‹จํ•œ ๊ฒƒ์ด ๋ฉ‹์ง€๊ณ  async.parallel๊ณผ ๊ฐ™์€ ๊ฒƒ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@niftylettuce Bluebird์—๋Š” ์ด๋ฏธ "async.parallel" ๊ธฐ๋Šฅ์ด ๊ธฐ๋ณธ ์ œ๊ณต๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ด๊ฒƒ์€ ๋ฌธ์ œ๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. ํ•œ ๋ฒˆ์˜ ์‹คํ–‰์œผ๋กœ ์‰ผํ‘œ๋กœ ๊ตฌ๋ถ„๋œ ์ฟผ๋ฆฌ๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์ •๋ง ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

ํ‘œ๊ธฐ๋งŒ ํ•˜๋ฉด ๋˜๋Š”๊ฑฐ ์•„๋‹Œ๊ฐ€์š”

    multipleStatements: true

๊ตฌ์„ฑ์˜ ์—ฐ๊ฒฐ ๋ธ”๋ก์—์„œ:
์˜ˆ

    connection: {
        host: 'localhost',
        user: 'superSecret',
        password: 'notGonnaTell',
         port: 8889,
        database: 'babelverse_core',
        multipleStatements: true
    }

์—ฌ๊ธฐ ๊ด€์‹ฌ ์žˆ๋Š” ์‚ฌ๋žŒ์ด ์žˆ์œผ๋ฉด ๋‹ค์Œ ๋ฆฌํŒฉํ„ฐ๋ง์—์„œ ์ด๋ฅผ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด ๋ช‡ ๊ฐ€์ง€ ์ƒˆ๋กœ์šด ์ž‘์—…์„ ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์ด์ƒ์ ์ธ API๊ฐ€ ๋ฌด์—‡์ธ์ง€ ๊ถ๊ธˆํ•ฉ๋‹ˆ๋‹ค... ๋‹จ์ผ ์ฒด์ธ์„ ์›ํ•˜์‹ญ๋‹ˆ๊นŒ?

knex
  .update('records_raw')
  .set({title: x}).where({id: 1})
  .end()
  .update('records_raw')
  .set({title: y}).where({id: 2})
  .spread((resultA, resultB) => {

  })

๋˜๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒƒ:

knex.multiQuery([
  knex.update('records_raw').set({title: x}).where({id: 1})
  knex.update('records_raw').set({title: y}).where({id: 2})
]).spread((resultA, resultB) => {

})

๋˜ํ•œ ์„ธ๋ฏธ์ฝœ๋ก ์œผ๋กœ ๋ถ„ํ• ํ•˜์—ฌ knex.raw ์ผ€์ด์Šค๋ฅผ ์ž๋™์œผ๋กœ ์ž‘๋™ํ•˜๊ฒŒ ๋งŒ๋“œ๋Š” ๊ฐ€๋Šฅ์„ฑ์„ ์‚ดํŽด๋ด…๋‹ˆ๋‹ค.

์›์‹œ ์ฟผ๋ฆฌ์—์„œ ์„ธ๋ฏธ์ฝœ๋ก ์œผ๋กœ ๋ถ„ํ• ํ•˜๋ฉด ์ข‹์€ ์‹œ์ž‘์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์‚ญ์ œ๊ฐ€ ์‚ฝ์ž…๋˜๊ธฐ ์ „์— ์ œ ์‹œ๊ฐ„์— ์™„๋ฃŒ๋˜์ง€ ์•Š๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜์—ฌ ์ค‘๋ณต ํ‚ค ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ๊ฐ™์€ ์ผ์„ํ•˜๊ณ ์žˆ๋‹ค

knex("mytable")
.where({
  id: 32423
})
.del()
.then( ->
  knex("mytable")
  .insert()
 ..... 

๋‹น์‹ ์€ ์š”์ ์„..

๋ธ์€ ์ œ ์‹œ๊ฐ„์— ์™„๋ฃŒ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

@tgriesser ๋‚ด ํˆฌํ‘œ๋Š” knex.multiQuery์— ๋Œ€ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

@tgrisser ๋‹จ์ผ ์ฟผ๋ฆฌ์—์„œ ์—ฌ๋Ÿฌ ๋ช…๋ น๋ฌธ์„ ์‹คํ–‰ํ•˜๋Š” ๊ธฐ๋Šฅ์— ๋Œ€ํ•œ ์—…๋ฐ์ดํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ? ๋‚ด๊ฐ€ ์„ ํ˜ธํ•˜๋Š”:

.update('records_raw')
.set({์ œ๋ชฉ: x}).where({ID: 1})
.๋()
.update('records_raw')
.set({์ œ๋ชฉ: y}).where({์•„์ด๋””: 2})
.then(ํ•จ์ˆ˜(๊ฒฐ๊ณผ) {
๊ฒฐ๊ณผ[0] //๊ฒฐ๊ณผ 1
๊ฒฐ๊ณผ[1] // ๊ฒฐ๊ณผ 2
})
.catch(ํ•จ์ˆ˜(์˜ค๋ฅ˜) {
console.log(์˜ค๋ฅ˜);
});

+1

์„ธ๋ฏธ์ฝœ๋ก ์—์„œ ์ ์ ˆํ•œ ๋ถ„ํ• ์„ ์ˆ˜ํ–‰ํ•˜๋ ค๋ฉด ๋ฐฉ์–ธ๋ณ„ ํŒŒ์„œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ „์ฒด ์›์‹œ ์ฟผ๋ฆฌ๋ฅผ ๊ตฌ๋ฌธ ๋ถ„์„ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํŠนํžˆ ๋ฌธ์ž์—ด์— ; ํฌํ•จ๋˜์–ด ์žˆ์œผ๋ฉด ๋ฌด์‹œํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ์€ ๊ตฌ๋ฌธ ๋ถ„์„์ด ์‰ฝ์ง€ ์•Š์€ ์œ ํšจํ•œ SQL์˜ ๋‘ ๊ฐ€์ง€ ์˜ˆ์ž…๋‹ˆ๋‹ค.

-- generic SQL
SELECT * FROM book WHERE title = 'Lord of the Rings; The Fellowship of the Ring';
-- MySQL specific
CREATE PROCEDURE dorepeat(p1 INT)
  BEGIN
    SET <strong i="9">@x</strong> = 0;
    REPEAT SET <strong i="10">@x</strong> = <strong i="11">@x</strong> + 1; UNTIL <strong i="12">@x</strong> > p1 END REPEAT;
  END

๋˜ํ•œ ์ฒซ ๋ฒˆ์งธ ๊ฒฝ์šฐ์—๋Š” 2๊ฐœ์˜ ๋ฌธ์œผ๋กœ ๋๋‚˜๋ฏ€๋กœ ์ฝ”๋“œ๋Š” ๋ถ„ํ• ์˜ ๋นˆ ๊ฒฐ๊ณผ๋ฅผ ๊ณ ๋ คํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์†”์งํžˆ ์ „๋ฐ˜์ ์œผ๋กœ ์ด๊ฒƒ์€ ๋‚˜์œ ์ƒ๊ฐ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. SQL ์ฃผ์ž… ๋ฐ ์ฟผ๋ฆฌ๋ฅผ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๋ถ„ํ• ํ•˜์ง€ ์•Š์„ ๊ฐ€๋Šฅ์„ฑ์ด ๋„ˆ๋ฌด ๋งŽ์Šต๋‹ˆ๋‹ค.

๋˜ํ•œ ์—ฌ๋Ÿฌ ๋ช…๋ น๋ฌธ์„ ์‹คํ–‰ํ•  ๋•Œ ๊ฑฐ์˜ ํ•ญ์ƒ ๋™์ผํ•œ ํŠธ๋žœ์žญ์…˜์—์„œ ๋ฐœ์ƒํ•˜๊ธฐ๋ฅผ ์›ํ•ฉ๋‹ˆ๋‹ค. Knex๋Š” ์ด๋ฏธ .transacting(function(transaction) { /* code */ }) ๊ตฌ๋ฌธ์œผ๋กœ ์ด ๋ฌธ์ œ๋ฅผ ์ž˜ ํ•ด๊ฒฐํ–ˆ์Šต๋‹ˆ๋‹ค. ํŠธ๋žœ์žญ์…˜์ด ํ•„์š”ํ•˜์ง€ ์•Š์€ ๋“œ๋ฌธ ๊ฒฝ์šฐ์— ๋ธ”๋ฃจ๋ฒ„๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ knex ๋ฌธ์„ ๊ฒฐํ•ฉํ•˜๊ณ  ๊ฒฐ๊ณผ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ์ด๋Ÿฌํ•œ ๋ฌธ์ œ ๋•Œ๋ฌธ์— ์ด๋Ÿฐ ์ผ์ด ๋ฐœ์ƒํ•ด์„œ๋Š” ์•ˆ ๋œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

:-1:

๋˜ํ•œ ์—ฌ๋Ÿฌ ๋ช…๋ น๋ฌธ์„ ์‹คํ–‰ํ•  ๋•Œ ๊ฑฐ์˜ ํ•ญ์ƒ ๋™์ผํ•œ ํŠธ๋žœ์žญ์…˜์—์„œ ๋ฐœ์ƒํ•˜๊ธฐ๋ฅผ ์›ํ•ฉ๋‹ˆ๋‹ค. Knex๋Š” ์ด๋ฏธ .transacting(function(transaction) { /* code */ }) ๊ตฌ๋ฌธ์œผ๋กœ ์ด ๋ฌธ์ œ๋ฅผ ์ž˜ ํ•ด๊ฒฐํ–ˆ์Šต๋‹ˆ๋‹ค. ํŠธ๋žœ์žญ์…˜์ด ํ•„์š”ํ•˜์ง€ ์•Š์€ ๋“œ๋ฌธ ๊ฒฝ์šฐ์— ๋ธ”๋ฃจ๋ฒ„๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ knex ๋ฌธ์„ ๊ฒฐํ•ฉํ•˜๊ณ  ๊ฒฐ๊ณผ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์–ด๋–ค ๊ฒฝ์šฐ์—๋Š” ์ด ๋‘ ๊ฐ€์ง€ ์ ‘๊ทผ ๋ฐฉ์‹๊ณผ ํ•˜๋‚˜์˜ ๋ช…๋ น์œผ๋กœ ์—ฌ๋Ÿฌ ๊ฐ’์„ ์„œ๋ฒ„์— ์ผ๊ด„ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ ์‚ฌ์ด์— _์—„์ฒญ๋‚œ_ ์„ฑ๋Šฅ ์ฐจ์ด๊ฐ€ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ๊ฒฝํ—˜์œผ๋กœ ๋ง์”€๋“œ๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ช…ํ™•ํ•˜๊ฒŒ ๊ตฌํ˜„ํ•˜๊ธฐ๊ฐ€ ๋งค์šฐ ์–ด๋ ต๋‹ค๋Š” ๊ฒƒ์„ ์ดํ•ดํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์•„์ง ์™„๋ฃŒ๋˜์ง€ ์•Š์•˜์ง€๋งŒ ์ด ๋ฌธ์ œ๋กœ ์ธํ•ด ํ”„๋กœ์ ํŠธ์—์„œ knex๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐ ํฌ๊ฒŒ ์ œํ•œ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ๋น„์Šทํ•œ ๋ฌธ์ œ๊ฐ€ ์žˆ์—ˆ๊ณ  ๊ทธ๊ฒƒ์„ ํ•ด๊ฒฐํ•  ์ˆ˜์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ๋ฅผ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค. https://github.com/tgriesser/knex/issues/1075

์ด ๊ธฐ๋Šฅ์— ๋Œ€ํ•œ ์‚ฌ์šฉ ์‚ฌ๋ก€๋ฅผ ๋ณผ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ํ•ด๊ฒฐ๋˜์ง€ ์•Š์œผ๋ฏ€๋กœ ์ด ํ‹ฐ์ผ“์„ ์ข…๋ฃŒํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ํ•˜๋‚˜๊ฐ€ ๋™์ผํ•œ ์—ฐ๊ฒฐ์—์„œ ์‹คํ–‰๋˜๋Š” ์ฟผ๋ฆฌ์˜ ์ˆœ์„œ์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์ง€๋Š” ๊ฒฝ์šฐ ํŠธ๋žœ์žญ์…˜์„ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ด '๋‹ค์ค‘ ์ฟผ๋ฆฌ' ์‚ฌ์šฉ์„ ์šฐ๋ฆฌ๊ฐ€ ์›ํ•˜๋Š” ๊ฒƒ์œผ๋กœ ๋งŒ๋“œ๋Š” ํ•œ ๊ฐ€์ง€๋Š” ๊ทธ๊ฒƒ์ด ์–ด๋–ค ๊ฒฝ์šฐ์—๋Š” ์ž ์žฌ์ ์ธ ์„ฑ๋Šฅ ํ–ฅ์ƒ์ด๋ผ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋ชจ๋“  ์ฟผ๋ฆฌ์™€ ๊ฒฐ๊ณผ๋ฅผ ์„œ๋ฒ„์™€ ์ฃผ๊ณ ๋ฐ›๋Š” ๋ฐ ํ•„์š”ํ•œ ์™•๋ณต ํšŸ์ˆ˜๊ฐ€ ์ค„์–ด๋“ญ๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ ์ธก์ • ๊ฐ€๋Šฅํ•œ ์‚ฌ์šฉ ์‚ฌ๋ก€๊ฐ€ ์žˆ๋Š” ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค. ๊ณผ๊ฑฐ์˜ ๊ฒฝํ—˜/๊ธฐ์–ต์—์„œ ๋งํ•˜๋Š” ๊ฒƒ๋ฟ...

@jurko-gospodnetic ์—ฐ๊ฒฐ ํ’€๋ง์ด ์—†๋Š” ๊ฒฝ์šฐ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๋Ÿฌ ์ฟผ๋ฆฌ๋ฅผ ๋ณด๋‚ด๋Š” ํ’€๋ง์€ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ด๋ฏธ ์ƒ์„ฑ๋œ TCP ์†Œ์ผ“์— ๋ฐ์ดํ„ฐ๋ฅผ ๋„ฃ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋˜ํ•œ ์„ฑ๋Šฅ์ด ์ถฉ๋ถ„ํžˆ ์ฑ„์›Œ์ง€์ง€ ์•Š์€ TCP ๋ฒ„ํผ์— ์˜์กดํ•˜๋Š” ๊ฒฝ์šฐ knex๋Š” ์ด๋ฏธ ๋„ˆ๋ฌด ๋Š๋ฆฝ๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ ๋“œ๋ผ์ด๋ฒ„๋ฅผ ์ง์ ‘ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

@jurko-gospodnetic์ด 5์›” 20์ผ์— ๋Œ“๊ธ€์„ ๋‚จ๊ฒผ์Šต๋‹ˆ๋‹ค.

์ด '๋‹ค์ค‘ ์ฟผ๋ฆฌ' ์‚ฌ์šฉ์„ ์šฐ๋ฆฌ๊ฐ€ ์›ํ•˜๋Š” ๊ฒƒ์œผ๋กœ ๋งŒ๋“œ๋Š” ํ•œ ๊ฐ€์ง€๋Š” ๊ทธ๊ฒƒ์ด ์–ด๋–ค ๊ฒฝ์šฐ์—๋Š” ์ž ์žฌ์ ์ธ ์„ฑ๋Šฅ ํ–ฅ์ƒ์ด๋ผ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋ชจ๋“  ์ฟผ๋ฆฌ์™€ ๊ฒฐ๊ณผ๋ฅผ ์„œ๋ฒ„์™€ ์ฃผ๊ณ ๋ฐ›๋Š” ๋ฐ ํ•„์š”ํ•œ ์™•๋ณต ํšŸ์ˆ˜๊ฐ€ ์ค„์–ด๋“ญ๋‹ˆ๋‹ค.

์ด ํŠน๋ณ„ํ•œ ์ด์œ ๋กœ ์—”ํ„ฐํ”„๋ผ์ด์ฆˆ๊ธ‰ ํ”„๋กœ์ ํŠธ์—์„œ node-mysql(mysqljs) ์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ์ด์œ ๋กœ ์ „์ฒด ํ”„๋กœ์ ํŠธ๋ฅผ knex.js๋กœ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ํ•˜๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

node-mysql(mysqljs) ๋“œ๋ผ์ด๋ฒ„์˜ ๋‹ค์ค‘ ๋ช…๋ น๋ฌธ ์ฟผ๋ฆฌ ๊ธฐ๋Šฅ์„ ํ™œ์šฉํ•˜์—ฌ ์ด๋Ÿฌํ•œ ์ž‘์—…์— ์ƒ๋‹นํ•œ ์„ฑ๋Šฅ ํ–ฅ์ƒ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

Knex๊ฐ€ ์ด๊ฒƒ์„ ์ง€์›ํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ๊ทธ๊ฒƒ์€ ๋‚˜์—๊ฒŒ ์‡ผ์Šคํ† ํผ๊ฐ€ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์ €๋Š” ์ด ์Šค๋ ˆ๋“œ๋ฅผ ๋˜์‚ด๋ ค ์งˆ๋ฌธํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ด์ œ Knex.js์—์„œ ํ•˜๋‚˜์˜ ๋ช…๋ น๋ฌธ์— ๋‹ค์ค‘ ์ฟผ๋ฆฌ๊ฐ€ ์ง€์›๋ฉ๋‹ˆ๊นŒ?

@nicholaswmin "์ƒ๋‹นํ•œ ์„ฑ๋Šฅ ํ–ฅ์ƒ"์ด ๋ฌด์—‡์„ ์˜๋ฏธํ•˜๋Š”์ง€ ์ข€ ๋” ๊ตฌ์ฒด์ ์œผ๋กœ ๋ง์”€ํ•ด ์ฃผ์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ? ์ด ๋ฐฉ๋ฒ•์œผ๋กœ ์—ฌ๋Ÿฌ ์ฟผ๋ฆฌ๋ฅผ ๋ณด๋‚ด๋Š” ๊ฒƒ์ด ๋™์ผํ•œ ์—ฐ๊ฒฐ์„ ํ†ตํ•ด ์—ฌ๋Ÿฌ ์ฟผ๋ฆฌ๋ฅผ ๋ณด๋‚ด๋Š” ๊ฒƒ๋ณด๋‹ค ํ›จ์”ฌ ๋” ํšจ์œจ์ ์ž…๋‹ˆ๋‹ค. ์–ด๋–ค ๋ฒค์น˜๋งˆํฌ?

@elhigu ๋ฒค์น˜๋งˆํฌ๋Š” ์—†์ง€๋งŒ ๊ณง๋ฐ”๋กœ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋งํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

DB์— ๋Œ€ํ•œ ๋‹จ์ผ ํ˜ธ์ถœ(๋ชจ๋“  ๋ช…๋ น๋ฌธ์ด ํฌํ•จ๋จ)์€ server-db ๋„คํŠธ์›Œํฌ ์™•๋ณต์„ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค.

๋ฐ˜๋ฉด์— ๋™์ผํ•œ ์—ฐ๊ฒฐ์„ ํ†ตํ•ด ์—ฌ๋Ÿฌ ์ฟผ๋ฆฌ๋ฅผ ๋ณด๋‚ด๋Š” ๊ฒƒ์€ ์€์ด์•Œ์ด ์•„๋‹™๋‹ˆ๋‹ค. ์ด ์†”๋ฃจ์…˜์€ ๋น„ํŠธ๋žœ์žญ์…˜ ํ๋ฆ„์—์„œ๋งŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ฌธ์ œ๋ฅผ ์ฐธ์กฐ

@nicholaswmin ์—„์ฒญ๋‚œ ์–‘์˜ ์ž‘์€ ์ฟผ๋ฆฌ๋ฅผ ๋ณด๋‚ด๊ณ  ๋Œ€๋ถ€๋ถ„ ๋ฌด์‹œํ•˜๊ฑฐ๋‚˜ ์ž‘์€ ๊ฒฐ๊ณผ๋ฅผ ๋ณด๋‚ด๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ? ์ด ๊ฒฝ์šฐ ๋“œ๋ผ์ด๋ฒ„๊ฐ€ ๊ฐ TCP ํŒจํ‚ท์— ๋Œ€ํ•ด ์—ฌ๋Ÿฌ ์ฟผ๋ฆฌ๋ฅผ ํŒจํ‚นํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ฐจ์ด์ ์ด ๋ˆˆ์— ๋Œ ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ์„ฑ๋Šฅ ์ฐจ์ด๋Š” ๋„คํŠธ์›Œํฌ ํŠธ๋ž˜ํ”ฝ ์–‘์—์„œ๋„ ์‰ฝ๊ฒŒ ์ธก์ •ํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋“œ๋ผ์ด๋ฒ„๊ฐ€ ์ด์ „ ํ˜ธ์ถœ์˜ ๊ฒฐ๊ณผ๋ฅผ ๋จผ์ € ๊ธฐ๋‹ค๋ฆฌ์ง€ ์•Š๊ณ  ๋ณ„๋„์˜ connection.query ํ˜ธ์ถœ์—์„œ DB๋กœ ์—ฌ๋Ÿฌ ์ฟผ๋ฆฌ๋ฅผ ๋ณด๋‚ด๋Š” ๊ฒƒ์„ ์ง€์›ํ•˜๋Š”์ง€ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡๊ฒŒ ํ•˜๋ฉด ์—ฌ๋Ÿฌ connection.query ๋˜๋Š” mysql ๋“œ๋ผ์ด๋ฒ„์—์„œ ์ง€์›ํ•˜๋Š” ๋‹จ์ผ ๋‹ค์ค‘ ์ฟผ๋ฆฌ๋ฅผ ๋ณด๋‚ด๋Š” ๊ฒƒ ์‚ฌ์ด์— TCP ํŠธ๋ž˜ํ”ฝ์— ํฐ ์ฐจ์ด๊ฐ€ ์—†์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

@elhigu ์‹ค์ œ๋กœ ์ž‘์€ ์ฟผ๋ฆฌ์ด์ง€๋งŒ ๊ฒฐ๊ณผ๊ฐ€ ํ•„์š”ํ•˜๋ฏ€๋กœ ํŠธ๋žœ์žญ์…˜/์ฟผ๋ฆฌ ์ฒด์ธ ์•„๋ž˜์—์„œ ๋” ๋งŽ์ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋””๋ฒ„๊ทธ ๋˜๋Š” ์œ ์‚ฌํ•œ ์˜ต์…˜์„ ํ†ตํ•ด ์ „์†ก๋˜๋Š” TCP ํŒจํ‚ท์„ ๋ณผ ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๊นŒ? ์ „์†ก๋˜๋Š” ์ฟผ๋ฆฌ ์ž์ฒด๊ฐ€ ์•„๋‹ˆ๋ผ ์‹ค์ œ ํŒจํ‚ท์ž…๋‹ˆ๋‹ค.

์‚ฌ์šฉ ์‚ฌ๋ก€:

๋‚ด ์‹œ์Šคํ…œ์—์„œ ์‚ฌ์šฉ์ž์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์—…๋ฐ์ดํŠธํ•  ๋•Œ ํ•ด๋‹น ์‚ฌ์šฉ์ž์— ๋Œ€ํ•œ ๊ฐ์‚ฌ ์ถ”์ (๋ณ€๊ฒฝ ์‚ฌํ•ญ)์„ ๊ณ„์‚ฐํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

// # PSEUDOCODE

// get current data of user
getUserData();
// set data of user
setUserData()
// get new data of user
getUserData()
// compute the audit trail by comparing the difference between before-set/after-set datums
computeAuditTrail(previousData, newData);

์œ„์˜ ๊ฐ ํ˜ธ์ถœ์€ ์—ฌ๋Ÿฌ DB ํ˜ธ์ถœ์„ ์ˆ˜ํ–‰ํ•˜๋ฏ€๋กœ ๋„คํŠธ์›Œํฌ ์™•๋ณต์ด ๋งŽ๋‹ค๊ณ  ์ƒ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

#1806์— ์–ธ๊ธ‰๋œ ๊ฒƒ์ฒ˜๋Ÿผ ์ˆœ์ฐจ์ ์ผ ํ•„์š”๊ฐ€ ์—†๋Š” ์ฟผ๋ฆฌ์— Promise.all() ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(๋Œ€๋ถ€๋ถ„ getData/setData ์˜ DB ํ˜ธ์ถœ์€ ์ˆœ์ฐจ์ ์ผ ํ•„์š”๊ฐ€ ์—†์Œ).

์ฟผ๋ฆฌ๊ฐ€ ํ’€์˜ ๋‹ค๋ฅธ ์—ฐ๊ฒฐ์—์„œ ์ „์†ก๋  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ํŠธ๋žœ์žญ์…˜์ด ์•„๋‹Œ ํ๋ฆ„์—์„œ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ํŠธ๋žœ์žญ์…˜์„ ์‚ฌ์šฉํ•˜์—ฌ ์œ„์˜ ํ๋ฆ„์„ ์ˆ˜ํ–‰ํ•˜์ž๋งˆ์ž ์ฟผ๋ฆฌ๊ฐ€ ๋‹จ์ผ ์—ฐ๊ฒฐ์—์„œ ์ „์†ก๋˜๊ธฐ ๋•Œ๋ฌธ์— ์†๋„๊ฐ€ ๋Š๋ ค์ง‘๋‹ˆ๋‹ค(์•ฝ 4๋ฐฐ).

์ฐธ๊ณ ๋กœ ์ €๋Š” MSSQL์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

Wireshark๋Š” ๋„คํŠธ์›Œํฌ ํŠธ๋ž˜ํ”ฝ์„ ๋ถ„์„ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” ๋งค์šฐ ์ผ๋ฐ˜์ ์ธ ํฌ๋กœ์Šค ํ”Œ๋žซํผ ๋„๊ตฌ์ž…๋‹ˆ๋‹ค.

๋‚˜๋Š” ๋…ธ๋“œ๋กœ ๊ทธ ์ˆ˜์ค€๊นŒ์ง€ ๋ณผ ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ์—†๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

ํ•œ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์€ ํ•˜๋‚˜์˜ ์ฟผ๋ฆฌ์— ํŒจํ‚น๋˜๊ฑฐ๋‚˜ ๋“œ๋ผ์ด๋ฒ„์— ๋ณ„๋„๋กœ ์ „๋‹ฌ๋œ ๋™์ผํ•œ ์–‘์˜ ์ฟผ๋ฆฌ๋ฅผ ๋ณด๋‚ผ ๋•Œ iptraf ๋˜๋Š” ๋‹ค๋ฅธ ๊ฒƒ์„ ์‚ฌ์šฉํ•˜์—ฌ ์†ก์ˆ˜์‹ ๋œ ๋ฐ์ดํ„ฐ์˜ ์–‘์„ ์ธก์ •ํ•˜๋Š” ๊ฒƒ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

multiQuery ๊ตฌ๋ฌธ์„ ๋ณด๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

๋ชจ๋“  ์—…๋ฐ์ดํŠธ ?
์ด์ œ multiQuery๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?
๊ทธ๋ ‡๋‹ค๋ฉด ์–ด๋–ค ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๊นŒ?

var knex = require("knex");
var _ = require("lodash");
var Promise = require("bluebird");

var knex = require('knex')({
    client: 'sqlite3',
    connection: {
        filename: "./data.sqlite"
    }
});

// Create Schema
let createScript = `

CREATE TABLE Class ( 
    Id                   integer NOT NULL  ,
    Name                 varchar(100)   ,
    CONSTRAINT Pk_Classes_Id PRIMARY KEY ( Id )
 );

CREATE TABLE Material ( 
    Id                   integer NOT NULL  ,
    Description          varchar(500)   ,
    CONSTRAINT Pk_Material_Id PRIMARY KEY ( Id )
 )

-- ... and so on (leave off the last semi or remove it later) ... 

`;

let statementPromises = _.map(createScript.split(';'), (statement) => {
    return knex.raw(statement);
});

Promise.all(statementPromises).then(function() {
    console.log('Schema generated. Populating...');

     // ...

๊ทธ๊ฒƒ์€ ํ•˜๋‚˜์˜ ์—ฌ๋Ÿฌ ์š”์ฒญ์ด ์•„๋‹Œ ๋ฃจํ”„ ์ผ ๋ฟ์ด๋ฉฐ SLOW์ž…๋‹ˆ๋‹ค.

@mscheffer ์งˆ๋ฌธ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

';'๋กœ ๊ตฌ๋ถ„๋œ ์—ฌ๋Ÿฌ ์ฟผ๋ฆฌ๋ฅผ ์‹คํ–‰ํ•˜๊ณ  ์‹ถ์€ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹จ์ผ ์ž„์›์— ์˜ํ•ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๊นŒ?

๋‚ด ๋Œ€๋‹ต์ด ํ•ด๊ฒฐํ•ฉ๋‹ˆ๋‹ค. ๋” ๋น ๋ฅด๊ณ  ๋” ๋‚˜์€ ์†”๋ฃจ์…˜์ด ์žˆ์œผ๋ฉด ์ œ๊ณตํ•˜์‹ญ์‹œ์˜ค.

@VictorioBerra ; ์—์„œ ๋ถ„ํ• ํ•˜๋Š” ๊ฒƒ์€ ์ผ๋ฐ˜์ ์œผ๋กœ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ฌธ์ž์—ด ๋ฆฌํ„ฐ๋Ÿด ๋ฐ ์ฃผ์„ ๋‚ด๋ถ€์— ; ๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ ๋คํ”„๋ฅผ ์ฝ๊ณ  ์žˆ๋‹ค๋ฉด SQL ๋คํ”„ ์ฝ”๋“œ๋ฅผ sqlite ์…ธ๋กœ ํŒŒ์ดํ”„ํ•˜๋Š” ๊ฒƒ์ด ์‰ฌ์šด ๋ฐฉ๋ฒ•์ด๋ผ๊ณ  ๋งํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ์Šฌํ”„๊ฒŒ๋„ ์ธ๋ฉ”๋ชจ๋ฆฌ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋Š” ๋‹จ์ผ ์—ฐ๊ฒฐ์ด๊ธฐ ๋•Œ๋ฌธ์— ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋˜ํ•œ ํ…œํ”Œ๋ฆฟ ๋ฌธ์ž์—ด ๋‚ด๋ถ€์— SQL ๋ฌธ์ž์—ด์„ ๋งŒ๋“  ๋‹ค์Œ ๋ถ„ํ• ํ•˜๋Š” ๊ฒฝ์šฐ knex.schema.* ๋นŒ๋”๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํšจ๊ณผ์ ์œผ๋กœ ๋™์ผํ•˜์ง€๋งŒ ๋” ์•ˆ์ „ํ•ฉ๋‹ˆ๋‹ค.

๋‚ด๊ฐ€ ์•„๋Š” ํ•œ ๋ชจ๋“  ๋ฐฉ์–ธ ๋“œ๋ผ์ด๋ฒ„์— ๋Œ€ํ•ด ๋‹จ์ผ ๋ช…๋ น์œผ๋กœ ์—ฌ๋Ÿฌ ์ฟผ๋ฆฌ๋ฅผ ์‹คํ–‰ํ•˜๋Š” ์ด ๊ธฐ๋Šฅ์„ ๋‹ฌ์„ฑํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์€ ์—†์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ๊ทธ๊ฒƒ์ด ์ง€์›๋˜๋Š” mysql๊ณผ oracledb ๋˜๋Š” mssql์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜๊ณ  mysql์„ ์‚ฌ์šฉํ•˜๋ฉด ์—ฌ์ „ํžˆ ๋งˆ์ง€๋ง‰ ์ฟผ๋ฆฌ์˜ ๊ฒฐ๊ณผ๋ฅผ ์‘๋‹ต์œผ๋กœ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(๊ทธ๋ž˜๋„ ๊ดœ์ฐฎ์„ ์ˆ˜ ์žˆ์Œ).

์—ฐ์†์ ์œผ๋กœ ์‹คํ–‰๋˜๋„๋ก ์—ฌ๋Ÿฌ ์ฟผ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์ •ํ•˜๋Š” ๊ฒฝ์šฐ ํŠธ๋žœ์žญ์…˜์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ์žŠ์ง€ ๋งˆ์‹ญ์‹œ์˜ค!

์›์‹œ SQL์„ ์‚ฌ์šฉํ•œ ๋‹ค์ค‘ ์ฟผ๋ฆฌ ์‹คํ–‰
๋‚˜๋Š” ์šฐ๋ฆฌ์˜ knex ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ์ค‘ ํ•˜๋‚˜๊ฐ€ CREATE DATABASE ์—ฐ์†์œผ๋กœ ์—ฌ๋Ÿฌ ๋ฒˆ ์‹คํ–‰ํ•ด์•ผ ํ•˜๋Š” ๋น„์Šทํ•œ ์ƒํ™ฉ์— ์ง๋ฉดํ–ˆ์Šต๋‹ˆ๋‹ค. ์ฟผ๋ฆฌ๋ฅผ ์„ธ๋ฏธ์ฝœ๋ก ์œผ๋กœ ๊ตฌ๋ถ„ํ•˜๊ณ  ์‹ถ์—ˆ์ง€๋งŒ knex์—์„œ ๊ตฌ๋ฌธ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด์— ๋Œ€ํ•œ ํ•ด๊ฒฐ์ฑ…์€ ์—ฐ๊ฒฐ ๊ฐœ์ฒด์— "multipleStatements": true ๋ฅผ ํฌํ•จํ•˜๋Š” ๊ฒƒ์ด๋ฏ€๋กœ ์ตœ์ข… ๊ฒฐ๊ณผ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

"host": "192.168.x.x",
"user": "userLogin",
"password": "userPassword",
"database": "schemaToUse",
"multipleStatements": true

๊ทธ ํ›„์— ๋‹ค์Œ๊ณผ ๊ฐ™์ด raw ๋ฌธ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

return knex.raw("CREATE DATABASE schema0; CREATE DATABASE schema1; CREATE DATABASE schema2")
   .then((result) => {
   })
   .catch((error) => {
   });

KNEX ์ฟผ๋ฆฌ ๋นŒ๋”๋ฅผ ์‚ฌ์šฉํ•œ ๋‹ค์ค‘ ์ฟผ๋ฆฌ ์‹คํ–‰
์›์‹œ SQL์„ ์ง์ ‘ ์ž‘์„ฑํ•˜๋Š” ๋Œ€์‹  knex ์ฟผ๋ฆฌ ๋นŒ๋”๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ Knex.QueryBuilder ์˜ ๊ฒฐ๊ณผ๋ฅผ ๋ฌธ์ž์—ด๋กœ ๋ณ€ํ™˜ํ•œ ๋‹ค์Œ ์—ฌ๋Ÿฌ ์ฟผ๋ฆฌ๋ฅผ ํ•จ๊ป˜ ์กฐ์ธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ์€ ํ•œ ๊ฐ€์ง€ ์˜ˆ์ž…๋‹ˆ๋‹ค.

// Suppose that we wanted to add 100 currency for all players in multiple games
const addCurrency = 100;
const updateCurrency = { currency: "currency + " + addCurrency };
const queries = [
   knex.table("game0.stats").update(updateCurrency),
   knex.table("game1.stats").update(updateCurrency),
   knex.table("game2.stats").update(updateCurrency),
];
const multiQuery = queries.join(";");
console.log(multiQuery);
return knex.raw(multiQuery)
   .then((result) => {
   })
   .catch((error) => {
   });

์ด๋Š” ๋˜ํ•œ ์—ฐ์†์ ์œผ๋กœ ์‹คํ–‰ํ•ด์•ผ ํ•˜๋Š” ์ค‘๋ณต ์ฟผ๋ฆฌ๋ฅผ ์ž‘์„ฑํ•  ๋•Œ ์‚ฌ๋žŒ์˜ ์‹ค์ˆ˜๋ฅผ ์ค„์ด๋Š” ๋ฐ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค. ์ด์™€ ๊ฐ™์€ ๊ฒƒ์œผ๋กœ ๋‹ค์‹œ ํŠธ๋žœ์žญ์…˜์œผ๋กœ ๋ž˜ํ•‘ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ๋Œ€๋ถ€๋ถ„ db ๋“œ๋ผ์ด๋ฒ„์— ์˜ํ•ด ์ œํ•œ๋˜๊ธฐ ๋•Œ๋ฌธ์— ๋‹ซ์„ ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์ตœ์†Œํ•œ ์ ์ ˆํ•œ ๊ธฐ๋Šฅ ์š”์ฒญ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

@AksharaKarikalan ์—ฌ๋Ÿฌ ํ•˜์œ„ ์ฟผ๋ฆฌ์™€ ๊ทธ ์‚ฌ์ด์˜ ๋นผ๊ธฐ๋ฅผ ์ˆ˜ํ–‰ํ•˜๋”๋ผ๋„ ์—ฌ์ „ํžˆ ๋‹จ์ผ ์ฟผ๋ฆฌ๋ฅผ ๋งŒ๋“ค๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์ด ๋ฌธ์ œ์™€ ๋ฌด๊ด€ํ•œ ๋Œ“๊ธ€์„ ์‚ญ์ œํ–ˆ์Šต๋‹ˆ๋‹ค. Stackoverflow๋Š” knex ์‚ฌ์šฉ ์š”์ฒญ์— ๋Œ€ํ•œ ์˜ฌ๋ฐ”๋ฅธ ์œ„์น˜์ž…๋‹ˆ๋‹ค.

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰