検索

私は、最初のプロジェクト (OT ポケモンと Habbo の最初の Web サイト) の開発を始めて以来、常に Raw SQL を選択してきました。正直に言うと、私は今でも独自のクエリを作成し、この「低レベル」レイヤーをより正確に制御することをとても楽しんでいます。非効率なクエリを特定して最適化するためにログを分析するのにすでに何日も費やしているため、ORM を使用しても完全に快適とは言えません。

しかし、私が Raw SQL を使用して作業した多くのコードベースでは、大部分に移行制御がなく、データベースも監視されていませんでした。すべてが即興で機能しました。「新しいフィールドが必要ですか?ALTER TABLE を実行して、新しい列を追加してください。」このアプローチはすべてのシナリオにおいて非常に有害であり、「運用環境ではどの列を上に移動する必要があるか?」、「どのような新しいエンティティが作成されたか?」、「環境は同期されているか?」など、いくつかの疑問が生じました。 — および他の多くの同様の問題。

私の問題の解決策

これらすべての問題に直面して、私は自分のルーティンと、一緒に働いているチームのルーティンをより健全なものにするために、新しいツールを導入することにしました。持っていた柔軟性を放棄したくはありませんでしたが、アプリケーションの自由度をより適切に制御したいとも考えていました。多くの調査を行った結果、これらの問題を解決するために最も完全であると考えられるツールを見つけました。Kysely は、実用的であることに加えて、完全にタイプセーフである TypeScript 用のクエリ ビルダーです。私にとって超重要なポイント。このライブラリに非常に興味を惹かれたので、Kysely と統合された他のオープン ソース ライブラリ用のプラグインを作成して、直接的および間接的にコミュニティに積極的に貢献し始めました。

ただし、Kysely を使用する場合の最大の困難の 1 つは、ORM とは異なり、エンティティや型/インターフェイスの自動生成がないことです。この作業はすべて手動で行う必要があり、少し疲れるかもしれません。ソリューションを調査中に、最終的に PostgreSQL に関連するすべてのプロジェクトで採用することになったツール、Kanel を見つけました。 Kanel はデータベース タイピングを自動的に生成し、Kysely を完全に補完します。

さらに、Kanel には、Kysely と直接使用するための追加機能があります: Kanel-Kysely。私はこのリポジトリに積極的に貢献し、移行テーブルの型フィルターや Zod オブジェクトのキャメルケースへの変換などの新機能の開発を支援してきました。

Kyselyの構成

NestJS を使用して次の例を説明します。したがって、コード内の構文や何かが理解できない場合は、NestJS のドキュメントを読むことをお勧めします。私の意見では、特に JavaScript を「エスケープ」したい場合には、これが最高の JavaScript フレームワークです。しかし、それは私の別の投稿のトピックです。

例を忠実に実行したい場合は、事前に NestJS が初期化されたリポジトリを用意しておく必要があります。ただし、独自のコードを開発することもできます。

最初に、Kysely 自体、その CLI、および Node.js 用の PostgreSQL モジュールをインストールする必要があります。

npm i kysely pg && npm i kysely-ctl --save-dev

次に、Kysely のプロジェクトのルートに構成ファイルを作成する必要があります。移行ファイルとシード ファイルにも Knex プレフィックスを使用します。

// kysely.config.ts

import "dotenv/config";

import { defineConfig, getKnexTimestampPrefix } from "kysely-ctl";
import { Pool } from "pg";

export default defineConfig({
  dialect: "pg",
  dialectConfig: {
    pool: new Pool({ connectionString: process.env.DATABASE_URL }),
  },
  migrations: {
    migrationFolder: "src/database/migrations",
    getMigrationPrefix: getKnexTimestampPrefix,
  },
  seeds: {
    seedFolder: "src/database/seeds",
    getSeedPrefix: getKnexTimestampPrefix,
  },
});

次に、ターミナルでコマンド npx kysely merge make create_user_table を実行します。これは、最初の移行の作成を担当します。次に、新しいユーザー テーブルを作成し、完了したら、コマンド npx kysely merge last を使用してデータベースでこの移行を実行します。

// 20241225222128_create_user_table.ts

import { sql, type Kysely } from 'kysely'


export async function up(db: Kysely<any>): Promise<void> {
  await db.schema
  .createTable("user")
  .addColumn("id", "serial", (col) => col.primaryKey())
  .addColumn("name", "text", (col) => col.notNull())
  .addColumn("email", "text", (col) => col.unique().notNull())
  .addColumn("password", "text", (col) => col.notNull())
  .addColumn("created_at", "timestamp", (col) =>
    col.defaultTo(sql`now()`).notNull(),
  )
  .execute();
}

export async function down(db: Kysely<any>): Promise<void> {
  await db.schema.dropTable("user").execute();
}
</void></any></void></any>

これらの手順がすべて完了したら、データベースのモジュールを作成しましょう。また、列をキャメルケースに変換するために Kysely プラグインを使用していることにも注目してください。

// src/database/database.module.ts

import { EnvService } from "@/env/env.service";
import { Global, Logger, Module } from "@nestjs/common";
import { CamelCasePlugin, Kysely, PostgresDialect } from "kysely";
import { Pool } from "pg";

export const DATABASE_CONNECTION = "DATABASE_CONNECTION";

@Global()
@Module({
  providers: [
    {
      provide: DATABASE_CONNECTION,
      useFactory: async (envService: EnvService) => {
        const dialect = new PostgresDialect({
          pool: new Pool({
            connectionString: envService.get("DATABASE_URL"),
          }),
        });

        const nodeEnv = envService.get("NODE_ENV");

        const db = new Kysely({
          dialect,
          plugins: [new CamelCasePlugin()],
          log: nodeEnv === "dev" ? ["query", "error"] : ["error"],
        });

        const logger = new Logger("DatabaseModule");

        logger.log("Successfully connected to database");

        return db;
      },
      inject: [EnvService],
    },
  ],
  exports: [DATABASE_CONNECTION],
})
export class DatabaseModule {}

カネルの構成

依存関係をインストールすることから始めましょう。

npm i kanel kanel-kysely --save-dev

次に、Kanel が動作を開始するための設定ファイルを作成しましょう。 CamelCaseHook (インターフェイスを CamelCase に変換するため) や kyselyTypeFilter (Kysely の移行テーブルを除外するため) などのいくつかのプラグインを使用することに注意してください。これらの機能の 1 つは、私が貢献してこれまでの作業を均一にすることができてうれしかったです。簡単です。

// .kanelrc.js

require("dotenv/config");

const { kyselyCamelCaseHook, makeKyselyHook, kyselyTypeFilter } = require("kanel-kysely");

/** @type {import('kanel').Config} */
module.exports = {
  connection: {
    connectionString: process.env.DATABASE_URL,
  },
  typeFilter: kyselyTypeFilter,
  preDeleteOutputFolder: true,
  outputPath: "./src/database/schema",
  preRenderHooks: [makeKyselyHook(), kyselyCamelCaseHook],
};

ファイルが作成されたら、ターミナルでコマンド npx kanel を実行します。設定ファイルで指定したパスにディレクトリが作成されたことに注意してください。このディレクトリはスキーマの名前 (この場合は Public) に対応し、その中には PublicSchema.tsUser.ts という 2 つの新しいファイルがあります。 。あなたの User.ts はおそらく次のようになります:

// @generated
// This file is automatically generated by Kanel. Do not modify manually.

import type { ColumnType, Selectable, Insertable, Updateable } from 'kysely';

/** Identifier type for public.user */
export type UserId = number & { __brand: 'UserId' };

/** Represents the table public.user */
export default interface UserTable {
  id: ColumnType<userid userid undefined>;

  name: ColumnType<string string>;

  email: ColumnType<string string>;

  password: ColumnType<string string>;

  createdAt: ColumnType<date date string undefined>;
}

export type User = Selectable<usertable>;

export type NewUser = Insertable<usertable>;

export type UserUpdate = Updateable<usertable>;

</usertable></usertable></usertable></date></string></string></string></userid>

ただし、最も重要なのは、このディレクトリ Public の外にあるファイル Database.ts です。これは、Kysely が理解できるように渡すためのものです。データベースの全体構造。ファイル app.service.ts 内に、DatabaseModule プロバイダーを挿入し、型 Database.
を Kysely に渡します。

npm i kysely pg && npm i kysely-ctl --save-dev

コード エディターは最初の移行で作成した列を正確に提案するため、Kanel が生成した型指定が正しく機能していることに注目してください。

Kysely   Kanel: a dupla perfeita

最終的な考慮事項

これは、私が個人的なプロジェクトや仕事でも (自由に使えるときは) 使用するのが大好きなデュオです。クエリ ビルダーは、Raw SQL が提供する柔軟性を好むと同時に、「より安全な」パスを選択するすべての人にとって不可欠なツールです。また、Kanel のおかげで、デバッグや新しい型付けの作成に費やす何時間も節約できました。この 2 つを使ってプロジェクトを作成することを強くお勧めします。絶対に後悔しないでしょう。

リポジトリ リンク: Frankenstein-nodejs

以上がキスリー・カネル:完璧なデュオの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
JavaScriptエンジンの理解:実装の詳細JavaScriptエンジンの理解:実装の詳細Apr 17, 2025 am 12:05 AM

JavaScriptエンジンが内部的にどのように機能するかを理解することは、開発者にとってより効率的なコードの作成とパフォーマンスのボトルネックと最適化戦略の理解に役立つためです。 1)エンジンのワークフローには、3つの段階が含まれます。解析、コンパイル、実行。 2)実行プロセス中、エンジンはインラインキャッシュや非表示クラスなどの動的最適化を実行します。 3)ベストプラクティスには、グローバル変数の避け、ループの最適化、constとletsの使用、閉鎖の過度の使用の回避が含まれます。

Python vs. JavaScript:学習曲線と使いやすさPython vs. JavaScript:学習曲線と使いやすさApr 16, 2025 am 12:12 AM

Pythonは、スムーズな学習曲線と簡潔な構文を備えた初心者により適しています。 JavaScriptは、急な学習曲線と柔軟な構文を備えたフロントエンド開発に適しています。 1。Python構文は直感的で、データサイエンスやバックエンド開発に適しています。 2。JavaScriptは柔軟で、フロントエンドおよびサーバー側のプログラミングで広く使用されています。

Python vs. JavaScript:コミュニティ、ライブラリ、リソースPython vs. JavaScript:コミュニティ、ライブラリ、リソースApr 15, 2025 am 12:16 AM

PythonとJavaScriptには、コミュニティ、ライブラリ、リソースの観点から、独自の利点と短所があります。 1)Pythonコミュニティはフレンドリーで初心者に適していますが、フロントエンドの開発リソースはJavaScriptほど豊富ではありません。 2)Pythonはデータサイエンスおよび機械学習ライブラリで強力ですが、JavaScriptはフロントエンド開発ライブラリとフレームワークで優れています。 3)どちらも豊富な学習リソースを持っていますが、Pythonは公式文書から始めるのに適していますが、JavaScriptはMDNWebDocsにより優れています。選択は、プロジェクトのニーズと個人的な関心に基づいている必要があります。

C/CからJavaScriptへ:すべてがどのように機能するかC/CからJavaScriptへ:すべてがどのように機能するかApr 14, 2025 am 12:05 AM

C/CからJavaScriptへのシフトには、動的なタイピング、ゴミ収集、非同期プログラミングへの適応が必要です。 1)C/Cは、手動メモリ管理を必要とする静的に型付けられた言語であり、JavaScriptは動的に型付けされ、ごみ収集が自動的に処理されます。 2)C/Cはマシンコードにコンパイルする必要がありますが、JavaScriptは解釈言語です。 3)JavaScriptは、閉鎖、プロトタイプチェーン、約束などの概念を導入します。これにより、柔軟性と非同期プログラミング機能が向上します。

JavaScriptエンジン:実装の比較JavaScriptエンジン:実装の比較Apr 13, 2025 am 12:05 AM

さまざまなJavaScriptエンジンは、各エンジンの実装原則と最適化戦略が異なるため、JavaScriptコードを解析および実行するときに異なる効果をもたらします。 1。語彙分析:ソースコードを語彙ユニットに変換します。 2。文法分析:抽象的な構文ツリーを生成します。 3。最適化とコンパイル:JITコンパイラを介してマシンコードを生成します。 4。実行:マシンコードを実行します。 V8エンジンはインスタントコンピレーションと非表示クラスを通じて最適化され、Spidermonkeyはタイプ推論システムを使用して、同じコードで異なるパフォーマンスパフォーマンスをもたらします。

ブラウザを超えて:現実世界のJavaScriptブラウザを超えて:現実世界のJavaScriptApr 12, 2025 am 12:06 AM

現実世界におけるJavaScriptのアプリケーションには、サーバー側のプログラミング、モバイルアプリケーション開発、モノのインターネット制御が含まれます。 2。モバイルアプリケーションの開発は、ReactNativeを通じて実行され、クロスプラットフォームの展開をサポートします。 3.ハードウェアの相互作用に適したJohnny-Fiveライブラリを介したIoTデバイス制御に使用されます。

next.jsを使用してマルチテナントSaaSアプリケーションを構築する(バックエンド統合)next.jsを使用してマルチテナントSaaSアプリケーションを構築する(バックエンド統合)Apr 11, 2025 am 08:23 AM

私はあなたの日常的な技術ツールを使用して機能的なマルチテナントSaaSアプリケーション(EDTECHアプリ)を作成しましたが、あなたは同じことをすることができます。 まず、マルチテナントSaaSアプリケーションとは何ですか? マルチテナントSaaSアプリケーションを使用すると、Singの複数の顧客にサービスを提供できます

next.jsを使用してマルチテナントSaaSアプリケーションを構築する方法(フロントエンド統合)next.jsを使用してマルチテナントSaaSアプリケーションを構築する方法(フロントエンド統合)Apr 11, 2025 am 08:22 AM

この記事では、許可によって保護されたバックエンドとのフロントエンド統合を示し、next.jsを使用して機能的なedtech SaaSアプリケーションを構築します。 FrontEndはユーザーのアクセス許可を取得してUIの可視性を制御し、APIリクエストがロールベースに付着することを保証します

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser は、オンライン試験を安全に受験するための安全なブラウザ環境です。このソフトウェアは、あらゆるコンピュータを安全なワークステーションに変えます。あらゆるユーティリティへのアクセスを制御し、学生が無許可のリソースを使用するのを防ぎます。

WebStorm Mac版

WebStorm Mac版

便利なJavaScript開発ツール

mPDF

mPDF

mPDF は、UTF-8 でエンコードされた HTML から PDF ファイルを生成できる PHP ライブラリです。オリジナルの作者である Ian Back は、Web サイトから「オンザフライ」で PDF ファイルを出力し、さまざまな言語を処理するために mPDF を作成しました。 HTML2FPDF などのオリジナルのスクリプトよりも遅く、Unicode フォントを使用すると生成されるファイルが大きくなりますが、CSS スタイルなどをサポートし、多くの機能強化が施されています。 RTL (アラビア語とヘブライ語) や CJK (中国語、日本語、韓国語) を含むほぼすべての言語をサポートします。ネストされたブロックレベル要素 (P、DIV など) をサポートします。