Knex: ๋‘ ๊ฐœ์˜ ์„œ๋กœ ๋‹ค๋ฅธ ์Šคํ‚ค๋งˆ์— ๊ฑธ์ณ ๋‘ ๊ฐœ์˜ ํ…Œ์ด๋ธ” ์กฐ์ธ(ํ•˜๋‚˜์˜ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค)

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

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

select * 
from user_schema.users as users
inner join account_schema.accounts  as accounts
on users.users.id = accounts.user_id

์•„๋งˆ๋„ kenx.js ์•„๋ž˜์— ์“ธ ์ˆ˜ ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ข‹์•„ ๋ณด์ด๋‚˜์š”?

knex.from('user_schema.users as users').innerJoin('account_schema.accounts as accounts', 
'users.id', 'accounts.user_id')

๊ทธ๋Ÿฌ๋‚˜ ๊ทธ๋•Œ ๋‚˜๋Š” ๋ณด์•˜๋‹ค. withSchema knex.js ์˜ต์…˜ ํ…Œ์ด๋ธ” ์ด๋ฆ„์— ์Šคํ‚ค๋งˆ๋ฅผ ์ ‘๋‘์‚ฌ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๋Œ€์‹  ํ•ด๋‹น ์˜ต์…˜์„ ์‚ฌ์šฉํ•˜๋ฉด ์–ด๋–ค ์ด์ ์ด ์žˆ์Šต๋‹ˆ๊นŒ? .withSchema ์˜ต์…˜์„ ์‚ฌ์šฉํ•˜์—ฌ ์„œ๋กœ ๋‹ค๋ฅธ ๋‘ ์Šคํ‚ค๋งˆ์˜ ์กฐ์ธ ํ…Œ์ด๋ธ”์„ ์กฐ์ธํ•˜๋ ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ•ฉ๋‹ˆ๊นŒ?

Knex.js Documentation 
------------------------
.withSchema([schemaName]) 
Specifies the schema to be used as prefix of table name.

knex.withSchema('public').select('*').from('users')

Outputs:
select * from `public`.`users`

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

๋ฌธ์„œ์—๋Š” Identifier Syntax, ์ฆ‰ ํ…Œ์ด๋ธ” ์ด๋ฆ„, ์—ด ์ด๋ฆ„์—๋Š” ์Šคํ‚ค๋งˆ๋ฅผ ์„ ํƒํ•  ์ˆ˜ ์žˆ๋Š” ๊ณต๊ฐ„์ด ์—†์œผ๋ฏ€๋กœ schemaName.tableName์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒฝ์šฐ ์ฟผ๋ฆฌ๊ฐ€ ์ž˜๋ชป ๋ Œ๋”๋ง๋  ์ˆ˜ ์žˆ๋‹ค๊ณ  ๋ฌธ์„œ์— ๋‚˜์™€ ์žˆ์Šต๋‹ˆ๋‹ค.

๋Œ€์‹  .withSchema('schemaName') ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ .withSchema ๋Š” ๋นŒ๋” ๋ธ”๋ก ์ „์ฒด์—์„œ ํ•˜๋‚˜์˜ ์Šคํ‚ค๋งˆ์—์„œ๋งŒ ์ž‘๋™ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ์•˜์Šต๋‹ˆ๋‹ค.

์ง€๊ธˆ๊นŒ์ง€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ž„์‹œ ํ•ด๊ฒฐ์ฑ…์ด ์žˆ์Šต๋‹ˆ๋‹ค.

  • speasure ์ฟผ๋ฆฌ์— .withSchema ๋ฅผ ์ „ํ˜€ ์‚ฌ์šฉํ•˜์ง€ ๋ง๊ณ  ํ…Œ์ด๋ธ” ์ด๋ฆ„ ๋ฌธ์ž์—ด์— ์Šคํ‚ค๋งˆ ์ด๋ฆ„์„ ํฌํ•จํ•˜์‹ญ์‹œ์˜ค.
    ์ด๊ฒƒ์€ ๋ฌธ์„œ์— ๋ฐ˜๋Œ€ํ•ฉ๋‹ˆ๋‹ค.

  • .withSchema ์™€ ํ•จ๊ป˜ ํ•˜์œ„ ์ฟผ๋ฆฌ ์‚ฌ์šฉ

    {
        let rows = await knex.withSchema("sandbox1")
            .select('first_name', 'last_name', 'phone', 'site', "sites.name as sname")
            .from('users')
            .leftJoin(
                knex.withSchema('public')
                    .table('sites')
                    .select()
                    .as("sites"),
                "sites.id",
                "users.site")
        console.log(rows)
    }

์ด ๋ฐฉ๋ฒ•์€ ํ•˜์œ„ ์ฟผ๋ฆฌ์—์„œ .as ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

  • .joinRaw() ์‚ฌ์šฉ
    {
        let queryBuilder = knex.withSchema("sandbox1")
            .select('first_name', 'last_name', 'phone', 'site', "sites.name as sname")
            .from('users')
            .joinRaw("left join public.sites as sites ON sites.id = users.site", [])
        let sql = queryBuilder.toSQL().toNative()
        let rows = await queryBuilder

        console.log((sql))
        console.log(rows)
    }
  • .raw() ์‚ฌ์šฉ
    {
        let { rows ,rowCount } = await knex
            .raw('SELECT users.first_name, users.last_name, users.phone, users.site, sites.name as sname FROM sandbox1.users, public.sites WHERE sites.id = users.site;');

        console.log(rows)
    }

์ด๊ฒƒ์€ knex๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ด์ ์ด ์ ์Šต๋‹ˆ๋‹ค.

  • ๋‹ค๋ฅธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋‚˜ ORM ๋˜๋Š” ๋“œ๋ผ์ด๋ฒ„๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

์ตœํ›„์˜ ํž˜.

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

์ด๊ฒƒ์— ๋Œ€ํ•œ ์–ด๋–ค ํ•ด๊ฒฐ์ฑ…?

๋ฌธ์„œ์—๋Š” Identifier Syntax, ์ฆ‰ ํ…Œ์ด๋ธ” ์ด๋ฆ„, ์—ด ์ด๋ฆ„์—๋Š” ์Šคํ‚ค๋งˆ๋ฅผ ์„ ํƒํ•  ์ˆ˜ ์žˆ๋Š” ๊ณต๊ฐ„์ด ์—†์œผ๋ฏ€๋กœ schemaName.tableName์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒฝ์šฐ ์ฟผ๋ฆฌ๊ฐ€ ์ž˜๋ชป ๋ Œ๋”๋ง๋  ์ˆ˜ ์žˆ๋‹ค๊ณ  ๋ฌธ์„œ์— ๋‚˜์™€ ์žˆ์Šต๋‹ˆ๋‹ค.

๋Œ€์‹  .withSchema('schemaName') ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ .withSchema ๋Š” ๋นŒ๋” ๋ธ”๋ก ์ „์ฒด์—์„œ ํ•˜๋‚˜์˜ ์Šคํ‚ค๋งˆ์—์„œ๋งŒ ์ž‘๋™ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ์•˜์Šต๋‹ˆ๋‹ค.

์ง€๊ธˆ๊นŒ์ง€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ž„์‹œ ํ•ด๊ฒฐ์ฑ…์ด ์žˆ์Šต๋‹ˆ๋‹ค.

  • speasure ์ฟผ๋ฆฌ์— .withSchema ๋ฅผ ์ „ํ˜€ ์‚ฌ์šฉํ•˜์ง€ ๋ง๊ณ  ํ…Œ์ด๋ธ” ์ด๋ฆ„ ๋ฌธ์ž์—ด์— ์Šคํ‚ค๋งˆ ์ด๋ฆ„์„ ํฌํ•จํ•˜์‹ญ์‹œ์˜ค.
    ์ด๊ฒƒ์€ ๋ฌธ์„œ์— ๋ฐ˜๋Œ€ํ•ฉ๋‹ˆ๋‹ค.

  • .withSchema ์™€ ํ•จ๊ป˜ ํ•˜์œ„ ์ฟผ๋ฆฌ ์‚ฌ์šฉ

    {
        let rows = await knex.withSchema("sandbox1")
            .select('first_name', 'last_name', 'phone', 'site', "sites.name as sname")
            .from('users')
            .leftJoin(
                knex.withSchema('public')
                    .table('sites')
                    .select()
                    .as("sites"),
                "sites.id",
                "users.site")
        console.log(rows)
    }

์ด ๋ฐฉ๋ฒ•์€ ํ•˜์œ„ ์ฟผ๋ฆฌ์—์„œ .as ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

  • .joinRaw() ์‚ฌ์šฉ
    {
        let queryBuilder = knex.withSchema("sandbox1")
            .select('first_name', 'last_name', 'phone', 'site', "sites.name as sname")
            .from('users')
            .joinRaw("left join public.sites as sites ON sites.id = users.site", [])
        let sql = queryBuilder.toSQL().toNative()
        let rows = await queryBuilder

        console.log((sql))
        console.log(rows)
    }
  • .raw() ์‚ฌ์šฉ
    {
        let { rows ,rowCount } = await knex
            .raw('SELECT users.first_name, users.last_name, users.phone, users.site, sites.name as sname FROM sandbox1.users, public.sites WHERE sites.id = users.site;');

        console.log(rows)
    }

์ด๊ฒƒ์€ knex๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ด์ ์ด ์ ์Šต๋‹ˆ๋‹ค.

  • ๋‹ค๋ฅธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋‚˜ ORM ๋˜๋Š” ๋“œ๋ผ์ด๋ฒ„๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

์ตœํ›„์˜ ํž˜.

@codinggirl ์˜ ๋‹ต๋ณ€์— ์„ธ๋ถ€ ์ •๋ณด๋ฅผ ํ•˜๋‚˜ ๋” ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

joinRaw() ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๋ฐ”์ธ๋”ฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฟผ๋ฆฌ ์ „์ฒด์—์„œ ๋™์ผํ•œ ๊ตฌ๋ฌธ์œผ๋กœ ์ฟผ๋ฆฌ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

    {
        const queryBuilder = knex.withSchema("sandbox1")
            .select('first_name', 'last_name', 'phone', 'site', "sites.name as sname")
            .from('users')
            .joinRaw("left join ?? ON ?? = ??", ["public.sites", "sites.id", "users.site"])
        const sql = queryBuilder.toString()
        console.log(sql)
    }

์ฐธ๊ณ : ์œ„์น˜ ๋ฐ”์ธ๋”ฉ ? ๊ฐ’์œผ๋กœ ํ•ด์„๋˜๊ณ  ?? ์‹๋ณ„์ž๋กœ ํ•ด์„๋ฉ๋‹ˆ๋‹ค.

PG์— ๋ฐ”์ธ๋”ฉ์ด ์žˆ๋Š” ์ถœ๋ ฅ:
"first_name", "last_name", "phone", "site", "sites"."name"์„ "sandbox1"์—์„œ "sname"์œผ๋กœ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค."users" ์™ผ์ชฝ ์กฐ์ธ "public"."sites" ON "sites". "id" = "์‚ฌ์šฉ์ž"."์‚ฌ์ดํŠธ"

MSSQL์— ๋Œ€ํ•œ ๋ฐ”์ธ๋”ฉ์ด ์žˆ๋Š” ์ถœ๋ ฅ:
[์ด๋ฆ„], [์„ฑ], [์ „ํ™”], [์‚ฌ์ดํŠธ], [์‚ฌ์ดํŠธ].[์ด๋ฆ„]์„ [sandbox1].[์‚ฌ์šฉ์ž] ์™ผ์ชฝ ์กฐ์ธ [๊ณต๊ฐœ].[์‚ฌ์ดํŠธ] ON [์‚ฌ์ดํŠธ]์—์„œ [์ด๋ฆ„]์œผ๋กœ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค. [id] = [์‚ฌ์šฉ์ž].[์‚ฌ์ดํŠธ]

ํ•œํŽธ, ๋ฐ”์ธ๋”ฉ ์—†์ด๋Š” ํ•ญ์ƒ ๋‹ค์Œ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
"first_name", "last_name", "phone", "site", "sites"๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค. "sandbox1"์—์„œ "sname"์œผ๋กœ "name"์„ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

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