Advertisement ยท 728 ร— 90
#
Hashtag
#drizzleorm
Advertisement ยท 728 ร— 90
Post image

#Svelte #Typescript #DrizzleORM #SQLite #Turso #HabitTracking #Code

blacknerd.hashnode.dev/creatures-of...

4 0 0 0
Preview
Creatures of Habit: Tauri, LLC & What's Next Follow my journey building Creatures of Habit. This update covers Tauri integration for desktop & mobile, UI improvements, forming an LLC, and future plans.

Creatures of Habit: Devlog Chronicles Part 3
#Svlete5 #Typescript #DrizzleORM #Turso #LLC #App
blacknerd.dev/creatures-of...

3 0 0 0
Post image

Who would win in a fight Drizzle or Kysely? ๐ŸฅŠ

Read our latest article to find out! We have compared these 2 popular solutions regarding:
โœ… Schema generation
โœ… Querying
โœ… Migrations

๐Ÿ‘‰ marmelab.com/blog/2025/06...

What's your bet? ๐Ÿ‘€

#DrizzleORM #Kysely #TypeScript

6 0 0 0

PS: Recognize the meme that inspired our episode art? ๐Ÿ˜

Bonus points if you spot it ๐Ÿ™ƒ

#AWS #AuroraDSQL #ServerlessSQL #PostgreSQL #CloudComputing #Fastify #DrizzleORM #Lambda #DevOps #MultiRegion #CostOptimization

1 0 0 0
Preview
Date - JavaScript | MDN JavaScript Date objects represent a single moment in time in a platform-independent format. Date objects encapsulate an integral number that represents milliseconds since the midnight at the beginning of January 1, 1970, UTC (the epoch).

In addition to `Date`, which has millisecond precision, I hope that Drizzle ORM also supports `Temporal.Instant`, which has nanosecond precision. ๐Ÿ˜ข

#JavaScript #Date #Temporal #Drizzle #DrizzleORM

2 1 0 0
Preview
Creatures of Habit: Devlog Chronicles - New Features & Code Wins Jump into my latest dev progress adding XP systems, custom notifications, and analytics to my habit tracking RPG app built with Svelte 5 and TypeScript.

Dropping a fresh blog post for my Creatures of Habit app! Check it out for all the new features and status updates.
#Svelte #Typescript #DrizzleORM #Turso #HabitTracking #AppDevelopement
blacknerd.dev/creatures-of...

3 0 0 0
์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ฐœ๋ฐœ ์ธก๋ฉด์—์„œ ๋ณธ Drizzle ORM ๋Œ€ Kysely ๋น„๊ต TypeScript๋กœ ๋ฐฑ์—”๋“œ ์„œ๋ฒ„๋ฅผ ๊ฐœ๋ฐœํ•˜๋ฉด์„œ ์ ์ ˆํ•œ ORM ์„ ํƒ์€ ํ•ญ์ƒ ์ค‘์š”ํ•œ ๊ฒฐ์ • ์ค‘ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค. ์ตœ๊ทผ ์ œ ํ”„๋กœ์ ํŠธ์—์„œ Drizzle ORM๊ณผ Kysely๋ฅผ ๋ชจ๋‘ ์‚ฌ์šฉํ•ด ๋ณผ ๊ธฐํšŒ๊ฐ€ ์žˆ์—ˆ๋Š”๋ฐ, ๊ฐœ์ธ์ ์œผ๋กœ๋Š” Drizzle ORM์ด ๋” ํŽธ๋ฆฌํ•˜๊ณ  ์ƒ์‚ฐ์„ฑ์ด ๋†’์•˜๋˜ ๊ฒฝํ—˜์„ ๊ณต์œ ํ•˜๊ณ ์ž ํ•ฉ๋‹ˆ๋‹ค. ## ๋‘ ORM์— ๋Œ€ํ•œ ๊ฐ„๋žตํ•œ ์†Œ๊ฐœ Drizzle ORM์€ TypeScript์šฉ ORM์œผ๋กœ, ํƒ€์ž… ์•ˆ์ „์„ฑ๊ณผ ์ง๊ด€์ ์ธ API๋ฅผ ๊ฐ•์ ์œผ๋กœ ๋‚ด์„ธ์šฐ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์Šคํ‚ค๋งˆ ์ •์˜๋ถ€ํ„ฐ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜, ์ฟผ๋ฆฌ ๋นŒ๋”๊นŒ์ง€ ํ’€์Šคํƒ ๊ฐœ๋ฐœ ๊ฒฝํ—˜์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. Kysely๋Š” 'ํƒ€์ž… ์•ˆ์ „ํ•œ SQL ์ฟผ๋ฆฌ ๋นŒ๋”'๋กœ ์ž์‹ ์„ ์†Œ๊ฐœํ•˜๋ฉฐ, ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ์˜ ํƒ€์ž… ์‹œ์Šคํ…œ์„ ํ™œ์šฉํ•ด ์ฟผ๋ฆฌ ์ž‘์„ฑ ์‹œ ํƒ€์ž… ์•ˆ์ „์„ฑ์„ ๋ณด์žฅํ•ฉ๋‹ˆ๋‹ค. ๋‘ ๋„๊ตฌ ๋ชจ๋‘ ํ›Œ๋ฅญํ•˜์ง€๋งŒ, ์ œ ๊ฐœ๋ฐœ ๊ฒฝํ—˜์— ๋น„์ถ”์–ด ๋ณผ ๋•Œ Drizzle ORM์ด ๋ช‡ ๊ฐ€์ง€ ์ธก๋ฉด์—์„œ ๋” ํŽธ๋ฆฌํ–ˆ์Šต๋‹ˆ๋‹ค. ## Drizzle ORM์„ ์„ ํ˜ธํ•˜๊ฒŒ ๋œ ์ด์œ  ### ์Šคํ‚ค๋งˆ ์ •์˜์˜ ์ง๊ด€์„ฑ Drizzle ORM์˜ ์Šคํ‚ค๋งˆ ์ •์˜ ๋ฐฉ์‹์€ ๋งค์šฐ ์ง๊ด€์ ์ด๊ณ  ์„ ์–ธ์ ์ž…๋‹ˆ๋‹ค: import { pgTable, serial, text, integer } from 'drizzle-orm/pg-core'; export const users = pgTable('users', { id: serial('id').primaryKey(), name: text('name').notNull(), email: text('email').unique().notNull(), age: integer('age') }); Drizzle ORM์€ ์ด ์Šคํ‚ค๋งˆ ์ •์˜๋กœ๋ถ€ํ„ฐ ์ž๋™์œผ๋กœ `CREATE TABLE` SQL์„ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์–ด, ์Šคํ‚ค๋งˆ์™€ ์ฝ”๋“œ๊ฐ€ ํ•ญ์ƒ ๋™๊ธฐํ™”๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฐ˜๋ฉด Kysely๋Š” ํƒ€์ž… ์ •์˜์— ๋” ์ค‘์ ์„ ๋‘๊ณ  ์žˆ์–ด ์Šคํ‚ค๋งˆ์™€ ํƒ€์ž… ์ •์˜๊ฐ€ ๋ถ„๋ฆฌ๋˜๋Š” ๊ฒฝํ–ฅ์ด ์žˆ์Šต๋‹ˆ๋‹ค: interface Database { users: { id: Generated<number>; name: string; email: string; age: number | null; }; } ์ด ํƒ€์ž… ์ •์˜๋Š” TypeScript ์ฝ”๋“œ์—์„œ ํƒ€์ž… ์•ˆ์ „์„ฑ์„ ์ œ๊ณตํ•˜์ง€๋งŒ, **์ด ํƒ€์ž… ์ •์˜๋งŒ์œผ๋กœ๋Š”`CREATE TABLE` SQL์„ ์ƒ์„ฑํ•  ์ˆ˜ ์—†๋‹ค๋Š” ๊ฒƒ์ด ๊ฒฐ์ •์ ์ธ ๋‹จ์ **์ž…๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ ํ…Œ์ด๋ธ”์„ ์ƒ์„ฑํ•˜๋ ค๋ฉด ๋ณ„๋„์˜ SQL ์Šคํฌ๋ฆฝํŠธ๋‚˜ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ํƒ€์ž…๊ณผ ์‹ค์ œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์Šคํ‚ค๋งˆ ๊ฐ„์˜ ๋ถˆ์ผ์น˜ ๊ฐ€๋Šฅ์„ฑ์„ ๋†’์ž…๋‹ˆ๋‹ค. Drizzle์˜ ์ ‘๊ทผ ๋ฐฉ์‹์ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์Šคํ‚ค๋งˆ์™€ TypeScript ํƒ€์ž…์„ ๋” ๊ธด๋ฐ€ํ•˜๊ฒŒ ์—ฐ๊ฒฐํ•ด์ฃผ์–ด ๊ฐœ๋ฐœ ๊ณผ์ •์—์„œ ํ˜ผ๋ž€์„ ์ค„์—ฌ์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค. ### ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ๊ฒฝํ—˜ Drizzle ORM์˜ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ๋„๊ตฌ(`drizzle-kit`)๋Š” ์ •๋ง ์ธ์ƒ์ ์ด์—ˆ์Šต๋‹ˆ๋‹ค. ์Šคํ‚ค๋งˆ ๋ณ€๊ฒฝ์‚ฌํ•ญ์„ ์ž๋™์œผ๋กœ ๊ฐ์ง€ํ•˜๊ณ  SQL ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ํŒŒ์ผ์„ ์ƒ์„ฑํ•ด์ฃผ๋Š” ๊ธฐ๋Šฅ์ด ๊ฐœ๋ฐœ ์›Œํฌํ”Œ๋กœ์šฐ๋ฅผ ํฌ๊ฒŒ ๊ฐœ์„ ํ–ˆ์Šต๋‹ˆ๋‹ค: npx drizzle-kit generate:pg ์ด ๋ช…๋ น์–ด ํ•˜๋‚˜๋กœ ์Šคํ‚ค๋งˆ ๋ณ€๊ฒฝ์‚ฌํ•ญ์— ๋Œ€ํ•œ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ํŒŒ์ผ์ด ์ƒ์„ฑ๋˜๋ฉฐ, ์ด๋ฅผ ๊ฒ€ํ† ํ•˜๊ณ  ์ ์šฉํ•˜๋Š” ๊ณผ์ •์ด ๋งค์šฐ ๊ฐ„๋‹จํ–ˆ์Šต๋‹ˆ๋‹ค. ๋ฐ˜๋ฉด Kysely์˜ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์€ ๋ณธ์งˆ์ ์œผ๋กœ ์ˆ˜๋™์ ์ž…๋‹ˆ๋‹ค. ๊ฐœ๋ฐœ์ž๊ฐ€ ์ง์ ‘ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ํŒŒ์ผ์„ ์ž‘์„ฑํ•ด์•ผ ํ•˜๋ฉฐ, ์Šคํ‚ค๋งˆ ๋ณ€๊ฒฝ์‚ฌํ•ญ์„ ์ž๋™์œผ๋กœ ๊ฐ์ง€ํ•˜๊ฑฐ๋‚˜ SQL์„ ์ƒ์„ฑํ•ด์ฃผ๋Š” ๊ธฐ๋Šฅ์ด ์—†์Šต๋‹ˆ๋‹ค: // Kysely์˜ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ์˜ˆ์‹œ async function up(db: Kysely<any>): Promise<void> { await db.schema .createTable('users') .addColumn('id', 'serial', (col) => col.primaryKey()) .addColumn('name', 'text', (col) => col.notNull()) .addColumn('email', 'text', (col) => col.unique().notNull()) .addColumn('age', 'integer') .execute(); } async function down(db: Kysely<any>): Promise<void> { await db.schema.dropTable('users').execute(); } ์ด๋Ÿฌํ•œ ์ˆ˜๋™ ๋ฐฉ์‹์€ ๋ณต์žกํ•œ ์Šคํ‚ค๋งˆ ๋ณ€๊ฒฝ์—์„œ ์‹ค์ˆ˜ํ•  ๊ฐ€๋Šฅ์„ฑ์ด ๋†’์•„์ง€๊ณ , ํŠนํžˆ ํฐ ํ”„๋กœ์ ํŠธ์—์„œ๋Š” ์ž‘์—…๋Ÿ‰์ด ์ƒ๋‹นํžˆ ์ฆ๊ฐ€ํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ Kysely์˜ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์—๋„ ๋‘ ๊ฐ€์ง€ ์ค‘์š”ํ•œ ์žฅ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค: 1. **TypeScript ๊ธฐ๋ฐ˜ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜** : Kysely์˜ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ์Šคํฌ๋ฆฝํŠธ๋Š” TypeScript๋กœ ์ž‘์„ฑ๋˜๊ธฐ ๋•Œ๋ฌธ์—, ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ๋กœ์ง์— ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋กœ์ง์„ ํ†ตํ•ฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, S3์™€ ๊ฐ™์€ ์˜ค๋ธŒ์ ํŠธ ์Šคํ† ๋ฆฌ์ง€์˜ ๋ฐ์ดํ„ฐ๋„ ํ•จ๊ป˜ ๋งˆ์ด๊ทธ๋ ˆ์ดํŠธํ•˜๋Š” ๋ณต์žกํ•œ ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฐ˜๋ฉด Drizzle ORM์€ SQL ๊ธฐ๋ฐ˜ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์ด๋ฏ€๋กœ ์ด๋Ÿฌํ•œ ํ†ตํ•ฉ์ด ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. 2. **์–‘๋ฐฉํ–ฅ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜** : Kysely๋Š” `up`๊ณผ `down` ํ•จ์ˆ˜๋ฅผ ๋ชจ๋‘ ์ •์˜ํ•˜์—ฌ ์—…๊ทธ๋ ˆ์ด๋“œ์™€ ๋‹ค์šด๊ทธ๋ ˆ์ด๋“œ๋ฅผ ๋ชจ๋‘ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ํŠนํžˆ ํŒ€ ํ˜‘์—… ํ™˜๊ฒฝ์—์„œ ์ค‘์š”ํ•œ๋ฐ, ๋‹ค๋ฅธ ๊ฐœ๋ฐœ์ž์˜ ๋ณ€๊ฒฝ์‚ฌํ•ญ๊ณผ ์ถฉ๋Œ์ด ๋ฐœ์ƒํ•  ๊ฒฝ์šฐ ๋กค๋ฐฑ์ด ํ•„์š”ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. Drizzle ORM์€ ํ˜„์žฌ ์—…๊ทธ๋ ˆ์ด๋“œ๋งŒ ์ง€์›ํ•˜๋ฉฐ, ๋‹ค์šด๊ทธ๋ ˆ์ด๋“œ ๊ธฐ๋Šฅ์ด ์—†์–ด ํ˜‘์—… ์‹œ ๋ถˆํŽธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฐธ๊ณ ๋กœ, Python ์ƒํƒœ๊ณ„์˜ SQLAlchemy ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ๋„๊ตฌ์ธ Alembic์€ ํ›จ์”ฌ ๋” ๋ฐœ์ „๋œ ํ˜•ํƒœ์˜ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. Alembic์€ ๋น„์„ ํ˜•์ ์ธ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ๊ฒฝ๋กœ(๋ธŒ๋žœ์น˜ํฌ์ธํŠธ ์ƒ์„ฑ ๊ฐ€๋Šฅ)๋ฅผ ์ง€์›ํ•˜์—ฌ ๋ณต์žกํ•œ ํŒ€ ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์—์„œ๋„ ์œ ์—ฐํ•˜๊ฒŒ ๋Œ€์‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด์ƒ์ ์œผ๋กœ๋Š” JavaScript/TypeScript ์ƒํƒœ๊ณ„์˜ ORM๋„ ์ด๋Ÿฌํ•œ ์ˆ˜์ค€์˜ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ๋„๊ตฌ๋ฅผ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์ด ๋ฐ”๋žŒ์งํ•ฉ๋‹ˆ๋‹ค. ### ๊ด€๊ณ„ ์„ค์ •์˜ ์šฉ์ด์„ฑ Drizzle ORM์—์„œ ํ…Œ์ด๋ธ” ๊ฐ„ ๊ด€๊ณ„ ์„ค์ •์ด ๋งค์šฐ ์ง๊ด€์ ์ด์—ˆ์Šต๋‹ˆ๋‹ค: import { relations } from 'drizzle-orm'; export const usersRelations = relations(users, ({ one, many }) => ({ profile: one(profiles, { fields: [users.id], references: [profiles.userId], }), posts: many(posts) })); ์ด ๋ฐฉ์‹์€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์„ค๊ณ„์˜ ๋ณธ์งˆ์ ์ธ, ๊ด€๊ณ„์ ์ธ ์ธก๋ฉด์„ ๋ช…ํ™•ํ•˜๊ฒŒ ํ‘œํ˜„ํ•ด์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค. ### ์ฟผ๋ฆฌ ์ž‘์„ฑ์˜ ํŽธ์˜์„ฑ๊ณผ ๋™์ผ ์ด๋ฆ„ ์นผ๋Ÿผ ๋ฌธ์ œ ์ฒ˜๋ฆฌ ๋‘ ORM ๋ชจ๋‘ ์ฟผ๋ฆฌ ์ž‘์„ฑ์„ ์œ„ํ•œ API๋ฅผ ์ œ๊ณตํ•˜์ง€๋งŒ, Drizzle์˜ ์ ‘๊ทผ ๋ฐฉ์‹์ด ๋” ์ง๊ด€์ ์ด๊ณ  ๊ด€๊ณ„ํ˜• ๋ชจ๋ธ์„ ํ™œ์šฉํ•˜๊ธฐ ์‰ฌ์› ์Šต๋‹ˆ๋‹ค: // Drizzle ORM - db.query ๋ฐฉ์‹์œผ๋กœ ๊ด€๊ณ„ ํ™œ์šฉ const result = await db.query.posts.findMany({ where: eq(posts.published, true), with: { user: true // ๊ฒŒ์‹œ๋ฌผ ์ž‘์„ฑ์ž ์ •๋ณด๋ฅผ ํ•จ๊ป˜ ์กฐํšŒ } }); // ๊ฒฐ๊ณผ ์ ‘๊ทผ์ด ์ง๊ด€์ ์ด๊ณ  ํƒ€์ž… ์•ˆ์ „ํ•จ console.log(result[0].title); // ๊ฒŒ์‹œ๋ฌผ ์ œ๋ชฉ console.log(result[0].user.name); // ์ž‘์„ฑ์ž ์ด๋ฆ„ - ๊ฐ์ฒด ๊ตฌ์กฐ๋กœ ๋ช…ํ™•ํ•˜๊ฒŒ ๊ตฌ๋ถ„๋จ console.log(result[0].user.id); // ์ž‘์„ฑ์ž ID - ๊ฒŒ์‹œ๋ฌผ ID์™€ ์ด๋ฆ„์ด ๊ฐ™์•„๋„ ๋ฌธ์ œ ์—†์Œ // Kysely const result = await db .selectFrom('posts') .where('posts.published', '=', true) .leftJoin('users', 'posts.userId', 'users.id') .selectAll(); // ๊ฒฐ๊ณผ ์ ‘๊ทผ ์‹œ ์นผ๋Ÿผ ์ด๋ฆ„ ์ถฉ๋Œ ๋ฌธ์ œ console.log(result[0].id) // ์˜ค๋ฅ˜: posts.id์™€ users.id ์ค‘ ์–ด๋–ค ๊ฒƒ์ธ์ง€ ๋ชจํ˜ธํ•จ console.log(result[0].name) // ์˜ค๋ฅ˜: ๋‘˜ ๋‹ค name ์นผ๋Ÿผ์ด ์žˆ๋‹ค๋ฉด ๋ชจํ˜ธํ•จ Drizzle์˜ ์ ‘๊ทผ ๋ฐฉ์‹์ด ํ…Œ์ด๋ธ”๊ณผ ์ปฌ๋Ÿผ์„ ์ฐธ์กฐํ•  ๋•Œ ํƒ€์ž… ์•ˆ์ „์„ฑ์„ ๋” ๊ฐ•๋ ฅํ•˜๊ฒŒ ๋ณด์žฅํ•˜๊ณ , ๊ด€๊ณ„๋ฅผ ํ™œ์šฉํ•œ ์ฟผ๋ฆฌ ์ž‘์„ฑ์ด ๋” ์ง๊ด€์ ์ด์—ˆ์Šต๋‹ˆ๋‹ค. ํŠนํžˆ **์—ฌ๋Ÿฌ ํ…Œ์ด๋ธ” ์กฐ์ธ ์‹œ ๋™์ผํ•œ ์ด๋ฆ„์˜ ์นผ๋Ÿผ ์ฒ˜๋ฆฌ** ๋ถ€๋ถ„์—์„œ Drizzle ORM์ด ํ›จ์”ฌ ๋” ํŽธ๋ฆฌํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ์ œ ๊ฐœ๋ฐœ ๊ฒฝํ—˜์—์„œ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ์ฐจ์ด์  ์ค‘ ํ•˜๋‚˜์˜€์Šต๋‹ˆ๋‹ค. // Drizzle ORM - ๋™์ผ ์ด๋ฆ„ ์นผ๋Ÿผ ์ฒ˜๋ฆฌ const result = await db.query.posts.findMany({ with: { user: true // posts.id์™€ users.id๊ฐ€ ๋ชจ๋‘ ์žˆ์ง€๋งŒ ์ž๋™์œผ๋กœ ๊ตฌ๋ถ„๋จ } }); // ๊ฒฐ๊ณผ์— ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ์ ‘๊ทผ ๊ฐ€๋Šฅ console.log(result[0].id); // ๊ฒŒ์‹œ๋ฌผ ID console.log(result[0].user.id); // ์‚ฌ์šฉ์ž ID - ๋ช…ํ™•ํ•˜๊ฒŒ ๊ตฌ๋ถ„๋จ console.log(result[0].user.name); // ์‚ฌ์šฉ์ž ์ด๋ฆ„ // Kysely - ๋™์ผ ์ด๋ฆ„ ์นผ๋Ÿผ ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•ด ๋ณ„์นญ ํ•„์š” const result = await db .selectFrom('posts') .leftJoin('users', 'posts.userId', 'users.id') .select([ 'posts.id as postId', // ๋ณ„์นญ ํ•„์ˆ˜ 'posts.title', 'posts.content', 'users.id as userId', // ๋ณ„์นญ ํ•„์ˆ˜ 'users.name as userName', // ์นผ๋Ÿผ ์ด๋ฆ„์ด ๊ฐ™์„ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ๋ณ„์นญ ํ•„์ˆ˜ 'users.email as userEmail' // ์ผ๊ด€์„ฑ์„ ์œ„ํ•ด ๋ชจ๋“  ์‚ฌ์šฉ์ž ๊ด€๋ จ ์นผ๋Ÿผ์— ์ ‘๋‘์–ด ํ•„์š” ]); // ๋ณ„์นญ์„ ํ†ตํ•œ ์ ‘๊ทผ console.log(result[0].postId); // ๊ฒŒ์‹œ๋ฌผ ID console.log(result[0].userId); // ์‚ฌ์šฉ์ž ID console.log(result[0].userName); // ์‚ฌ์šฉ์ž ์ด๋ฆ„ Drizzle ORM์€ ํ…Œ์ด๋ธ”๊ณผ ์นผ๋Ÿผ์„ ๊ฐ์ฒด๋กœ ์ฐธ์กฐํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ๋™์ผํ•œ ์ด๋ฆ„์˜ ์นผ๋Ÿผ์ด ์žˆ์–ด๋„ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ๊ณ„์ธต ๊ตฌ์กฐ๋กœ ์ฒ˜๋ฆฌ๋˜๋ฉฐ ํƒ€์ž… ์ถ”๋ก ๋„ ์ •ํ™•ํ•˜๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ๋ฐ˜๋ฉด Kysely์—์„œ๋Š” ๋ฌธ์ž์—ด ๊ธฐ๋ฐ˜ ์ ‘๊ทผ ๋ฐฉ์‹ ๋•Œ๋ฌธ์— ๋ณ„์นญ์„ ์ˆ˜๋™์œผ๋กœ ์ง€์ •ํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์•˜๊ณ , ๋ณต์žกํ•œ ์กฐ์ธ์—์„œ ์ด๋Ÿฐ ์ž‘์—…์ด ๋ฒˆ๊ฑฐ๋กœ์›Œ์กŒ์Šต๋‹ˆ๋‹ค. ํŠนํžˆ ์—ฌ๋Ÿฌ ํ…Œ์ด๋ธ”์— ๊ฐ™์€ ์ด๋ฆ„์˜ ์นผ๋Ÿผ์ด ๋งŽ์„์ˆ˜๋ก ๋ชจ๋“  ์นผ๋Ÿผ์— ๋ช…์‹œ์ ์ธ ๋ณ„์นญ์„ ์ง€์ •ํ•ด์•ผ ํ•˜๋Š” ๋ถˆํŽธํ•จ์ด ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ Drizzle ORM์€ ๊ฒฐ๊ณผ ํƒ€์ž…์„ ์ž๋™์œผ๋กœ ์ •ํ™•ํ•˜๊ฒŒ ์ถ”๋ก ํ•ด์ฃผ์–ด ๋ณ„๋„์˜ ํƒ€์ž… ์ง€์ • ์—†์ด๋„ ์•ˆ์ „ํ•˜๊ฒŒ ๊ฒฐ๊ณผ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ## Kysely์˜ ์žฅ์  ๋ฌผ๋ก  Kysely๋„ ์—ฌ๋Ÿฌ ๊ฐ•์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค: 1. **๋” ๊ฐ€๋ฒผ์šด ๊ตฌ์กฐ** : ํ•„์š”ํ•œ ๊ธฐ๋Šฅ๋งŒ ํฌํ•จํ•  ์ˆ˜ ์žˆ๋Š” ๋ชจ๋“ˆํ™”๋œ ๊ตฌ์กฐ 2. **SQL์— ๋” ๊ฐ€๊นŒ์šด ์ ‘๊ทผ** : SQL ๊ตฌ๋ฌธ์— ๋งค์šฐ ์ถฉ์‹คํ•œ API ์„ค๊ณ„ 3. **์œ ์—ฐ์„ฑ** : ๋ณต์žกํ•œ ์ฟผ๋ฆฌ์—์„œ ๋•Œ๋กœ ๋” ์œ ์—ฐํ•œ ์ž‘์„ฑ์ด ๊ฐ€๋Šฅ ๋˜ํ•œ ์•ž์„œ ์–ธ๊ธ‰ํ–ˆ๋“ฏ์ด, Kysely์˜ TypeScript ๊ธฐ๋ฐ˜ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜๊ณผ ์–‘๋ฐฉํ–ฅ(up/down) ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ์ง€์›์€ ํŠน์ • ์ƒํ™ฉ์—์„œ Drizzle ORM๋ณด๋‹ค ์šฐ์œ„์— ์žˆ๋Š” ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค. ## SQLAlchemy์™€์˜ ๋น„๊ต ๋ฐ ์•ž์œผ๋กœ์˜ ๊ธฐ๋Œ€ JavaScript/TypeScript ์ƒํƒœ๊ณ„์˜ ORM์„ ์ด์•ผ๊ธฐํ•˜๊ธฐ ์ „์—, ์—ฌ๋Ÿฌ ์–ธ์–ด ์ค‘์—์„œ๋„ Python์˜ SQLAlchemy๋Š” ํŠน๋ณ„ํ•œ ์œ„์น˜๋ฅผ ์ฐจ์ง€ํ•ฉ๋‹ˆ๋‹ค. ๊ฐœ์ธ์ ์œผ๋กœ ์—ฌํƒœ ์‚ฌ์šฉํ•ด๋ณธ ๋‹ค์–‘ํ•œ ์–ธ์–ด์˜ ORM ์ค‘์—์„œ SQLAlchemy๊ฐ€ ๊ฐ€์žฅ ๊ธฐ๋Šฅ์ด ํ’๋ถ€ํ•˜๊ณ  ๊ฐ•๋ ฅํ•˜๋‹ค๊ณ  ๋А๊ผˆ์Šต๋‹ˆ๋‹ค. ๋ณต์žกํ•œ ์ฟผ๋ฆฌ ๊ตฌ์„ฑ, ๊ณ ๊ธ‰ ๊ด€๊ณ„ ๋งคํ•‘, ํŠธ๋žœ์žญ์…˜ ๊ด€๋ฆฌ, ์ด๋ฒคํŠธ ์‹œ์Šคํ…œ ๋“ฑ SQLAlchemy์˜ ๊ธฐ๋Šฅ์€ ์ •๋ง ๋ฐฉ๋Œ€ํ•ฉ๋‹ˆ๋‹ค. Drizzle ORM์€ JavaScript ์ƒํƒœ๊ณ„์—์„œ ๋งค์šฐ ์ธ์ƒ์ ์ธ ๋ฐœ์ „์„ ์ด๋ฃจ์—ˆ์ง€๋งŒ, ์•„์ง SQLAlchemy์˜ ๊ฒฝ์ง€์—๋Š” ์ด๋ฅด์ง€ ๋ชปํ–ˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ํŠนํžˆ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ถ€๋ถ„์—์„œ SQLAlchemy์˜ ์„ฑ์ˆ™๋„์™€ ๊ธฐ๋Šฅ ํ’๋ถ€ํ•จ์ด ๋‹๋ณด์ž…๋‹ˆ๋‹ค: * ๋ณต์žกํ•œ ์„œ๋ธŒ์ฟผ๋ฆฌ์™€ ์œˆ๋„์šฐ ํ•จ์ˆ˜ ์ง€์› * ๋‹ค์–‘ํ•œ ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ์™€ ํ›… * ๋‹ค์–‘ํ•œ ์ƒ์† ์ „๋žต * ๋ณต์žกํ•œ ํŠธ๋žœ์žญ์…˜ ๊ด€๋ฆฌ์™€ ์„ธ์…˜ ๊ด€๋ฆฌ * ๋Œ€๊ทœ๋ชจ ํ”„๋กœ์ ํŠธ์—์„œ ๊ฒ€์ฆ๋œ ์•ˆ์ •์„ฑ * Alembic์„ ํ†ตํ•œ ๋น„์„ ํ˜•์  ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ์ง€์› * ๋†€๋ผ์šธ ์ •๋„๋กœ ๋ฐฉ๋Œ€ํ•˜๊ณ  ์ƒ์„ธํ•œ ๋ฌธ์„œํ™” ## ๊ฒฐ๋ก  ๋‘ ORM ๋ชจ๋‘ ํ›Œ๋ฅญํ•œ ๋„๊ตฌ์ด์ง€๋งŒ, ์ œ ๊ฐœ๋ฐœ ์Šคํƒ€์ผ๊ณผ ํ”„๋กœ์ ํŠธ ์š”๊ตฌ์‚ฌํ•ญ์—๋Š” Drizzle ORM์ด ๋” ์ž˜ ๋งž์•˜์Šต๋‹ˆ๋‹ค. ํŠนํžˆ ์Šคํ‚ค๋งˆ ์ •์˜์˜ ์ง๊ด€์„ฑ, ๊ฐ•๋ ฅํ•œ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ๋„๊ตฌ, ๊ทธ๋ฆฌ๊ณ  ์ „๋ฐ˜์ ์ธ ๊ฐœ๋ฐœ์ž ๊ฒฝํ—˜ ์ธก๋ฉด์—์„œ Drizzle ORM์ด ๋” ์ƒ์‚ฐ์ ์ธ ๊ฐœ๋ฐœ์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ด์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค. ๋™์ผ ์ด๋ฆ„ ์นผ๋Ÿผ ์ฒ˜๋ฆฌ์™€ ๊ฐ™์€ ์‹ค์งˆ์ ์ธ ๋ฌธ์ œ์—์„œ Drizzle ORM์˜ ๊ฐ์ฒด ๊ธฐ๋ฐ˜ ์ ‘๊ทผ ๋ฐฉ์‹์ด ๊ฐ€์ ธ๋‹ค์ฃผ๋Š” ํŽธ๋ฆฌํ•จ์€ ์‹ค์ œ ํ”„๋กœ์ ํŠธ์—์„œ ํฐ ์ฐจ์ด๋ฅผ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. ORM ์„ ํƒ์€ ๊ฒฐ๊ตญ ํ”„๋กœ์ ํŠธ ํŠน์„ฑ๊ณผ ๊ฐœ์ธ ์„ ํ˜ธ๋„์— ํฌ๊ฒŒ ์ขŒ์šฐ๋ฉ๋‹ˆ๋‹ค. ์ƒˆ๋กœ์šด ํ”„๋กœ์ ํŠธ๋ฅผ ์‹œ์ž‘ํ•œ๋‹ค๋ฉด ๋‘ ๋„๊ตฌ ๋ชจ๋‘ ๊ฐ„๋‹จํžˆ ํ…Œ์ŠคํŠธํ•ด๋ณด๊ณ  ์ž์‹ ์˜ ์›Œํฌํ”Œ๋กœ์šฐ์— ๋” ์ ํ•ฉํ•œ ๊ฒƒ์„ ์„ ํƒํ•˜๋Š” ๊ฒƒ์ด ์ข‹๊ฒ ์ง€๋งŒ, ์ œ ๊ฒฝ์šฐ์—๋Š” Drizzle ORM์ด ๋ช…ํ™•ํ•œ ์Šน์ž์˜€์Šต๋‹ˆ๋‹ค. ์•ž์œผ๋กœ Drizzle ORM์ด ๋”์šฑ ๋ฐœ์ „ํ•˜์—ฌ SQLAlchemy ์ˆ˜์ค€์˜ ํ’๋ถ€ํ•œ ๊ธฐ๋Šฅ๊ณผ ์œ ์—ฐ์„ฑ์„ ์ œ๊ณตํ•˜๊ฒŒ ๋˜๊ธธ ๋ฐ”๋ž๋‹ˆ๋‹ค. JavaScript/TypeScript ์ƒํƒœ๊ณ„์—๋„ ๊ทธ๋Ÿฐ ์ˆ˜์ค€์˜ ๊ฐ•๋ ฅํ•œ ORM์ด ์žˆ์œผ๋ฉด ์ข‹๊ฒ ์Šต๋‹ˆ๋‹ค. ๋‹คํ–‰ํžˆ๋„ Drizzle ORM์€ ๊ณ„์†ํ•ด์„œ ๋ฐœ์ „ํ•˜๊ณ  ์žˆ์œผ๋ฉฐ, ๊ทธ ๋ฐœ์ „ ์†๋„๋ฅผ ๋ณด๋ฉด ๊ธฐ๋Œ€๊ฐ€ ํฝ๋‹ˆ๋‹ค. ์—ฌ๋Ÿฌ๋ถ„์˜ ๊ฒฝํ—˜์€ ์–ด๋–ค๊ฐ€์š”? ๋‹ค๋ฅธ ORM ๋„๊ตฌ๋‚˜ ์–ธ์–ด๋ฅผ ์‚ฌ์šฉํ•ด๋ณด์…จ๋‹ค๋ฉด ์˜๊ฒฌ์„ ๊ณต์œ ํ•ด์ฃผ์„ธ์š”!
1 4 0 1
Preview
Creatures of Habit: Coding Challenges & Progress Check Building 'Creatures of Habit', a habit-tracking RPG app. Tackling coding challenges, TypeScript vs PHP, and a 24-day streak. Follow my journey and progress.

Progress update on my "Creatures of Habit" RPG-style habit-tracking app ๐Ÿค˜๐Ÿพ
blacknerd.dev/creatures-of...
#Typescript #Svelte #DrizzleORM #Turso #WebDevelopment #HabitTracker

2 1 1 0
Quick Payload 3 Custom Component Example
Quick Payload 3 Custom Component Example YouTube video by Aaron Saunders

๐Ÿ‘‰๐Ÿพ Video Tutorial and Source Code

๐Ÿ“บ Quick Payload 3 Custom Component Example - create a header in the admin collection view that summarizes collect information and adds buttons to quickly filter the list

youtu.be/W_Da3Sp4Lgw?...

#payloadcms #drizzleORM #headlesscms #nextjs

1 0 0 0
Preview
Custom Authentication in SvelteKit: Session & Cookie Overview Explore building custom authentication in SvelteKit without auth libraries. Learn about session management, cookie handling, and secure token storage.

Was forced to learn a bit about implementing #authentication from scratch and it was worth it.
#TypeScript #Python #DrizzleORM #Svelte

blacknerd.dev/how-to-build...

3 0 0 0

I also love the end to end type safety when additionally using an ORM and TypeScript
#drizzleorm #remix

0 0 0 0
Drizzle ORM - next gen TypeScript ORM. Drizzle ORM is a lightweight and performant TypeScript ORM with developer experience in mind.

๐Ÿฒ #DrizzleORM: A headless #TypeScript ORM supporting #PostgreSQL, #MySQL & #SQLite. Features SQL-like queries, zero dependencies, serverless-ready design & both relational/SQL APIs. #opensource #database #webdev orm.drizzle.team

0 0 0 0

Our product was struggling with sending lots of updates to pg db, so made this package to help with batch updates with #DrizzleORM

github.com/greybox3D/utilโ€ฆ

Works with postgres at the moment, feel free to contribute!

I'm unsure if it's the best way, lmk!

#buildinpublic

0 0 1 0