検索

私は、最初のプロジェクト (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 までご連絡ください。
Python vs. JavaScript:ジョブに適したツールを選択するPython vs. JavaScript:ジョブに適したツールを選択するMay 08, 2025 am 12:10 AM

PythonまたはJavaScriptを選択するかどうかは、プロジェクトの種類によって異なります。1)データサイエンスおよび自動化タスクのPythonを選択します。 2)フロントエンドとフルスタック開発のためにJavaScriptを選択します。 Pythonは、データ処理と自動化における強力なライブラリに好まれていますが、JavaScriptはWebインタラクションとフルスタック開発の利点に不可欠です。

PythonとJavaScript:それぞれの強みを理解するPythonとJavaScript:それぞれの強みを理解するMay 06, 2025 am 12:15 AM

PythonとJavaScriptにはそれぞれ独自の利点があり、選択はプロジェクトのニーズと個人的な好みに依存します。 1. Pythonは、データサイエンスやバックエンド開発に適した簡潔な構文を備えた学習が簡単ですが、実行速度が遅くなっています。 2。JavaScriptはフロントエンド開発のいたるところにあり、強力な非同期プログラミング機能を備えています。 node.jsはフルスタックの開発に適していますが、構文は複雑でエラーが発生しやすい場合があります。

JavaScriptのコア:CまたはCの上に構築されていますか?JavaScriptのコア:CまたはCの上に構築されていますか?May 05, 2025 am 12:07 AM

javascriptisnotbuiltoncorc;それは、解釈されていることを解釈しました。

JavaScriptアプリケーション:フロントエンドからバックエンドまでJavaScriptアプリケーション:フロントエンドからバックエンドまでMay 04, 2025 am 12:12 AM

JavaScriptは、フロントエンドおよびバックエンド開発に使用できます。フロントエンドは、DOM操作を介してユーザーエクスペリエンスを強化し、バックエンドはnode.jsを介してサーバータスクを処理することを処理します。 1.フロントエンドの例:Webページテキストのコンテンツを変更します。 2。バックエンドの例:node.jsサーバーを作成します。

Python vs. Javascript:どの言語を学ぶべきですか?Python vs. Javascript:どの言語を学ぶべきですか?May 03, 2025 am 12:10 AM

PythonまたはJavaScriptの選択は、キャリア開発、学習曲線、エコシステムに基づいている必要があります。1)キャリア開発:Pythonはデータサイエンスとバックエンド開発に適していますが、JavaScriptはフロントエンドおよびフルスタック開発に適しています。 2)学習曲線:Python構文は簡潔で初心者に適しています。 JavaScriptの構文は柔軟です。 3)エコシステム:Pythonには豊富な科学コンピューティングライブラリがあり、JavaScriptには強力なフロントエンドフレームワークがあります。

JavaScriptフレームワーク:最新のWeb開発のパワーJavaScriptフレームワーク:最新のWeb開発のパワーMay 02, 2025 am 12:04 AM

JavaScriptフレームワークのパワーは、開発を簡素化し、ユーザーエクスペリエンスとアプリケーションのパフォーマンスを向上させることにあります。フレームワークを選択するときは、次のことを検討してください。1。プロジェクトのサイズと複雑さ、2。チームエクスペリエンス、3。エコシステムとコミュニティサポート。

JavaScript、C、およびブラウザの関係JavaScript、C、およびブラウザの関係May 01, 2025 am 12:06 AM

はじめに私はあなたがそれを奇妙に思うかもしれないことを知っています、JavaScript、C、およびブラウザは正確に何をしなければなりませんか?彼らは無関係であるように見えますが、実際、彼らは現代のウェブ開発において非常に重要な役割を果たしています。今日は、これら3つの間の密接なつながりについて説明します。この記事を通して、JavaScriptがブラウザでどのように実行されるか、ブラウザエンジンでのCの役割、およびそれらが協力してWebページのレンダリングと相互作用を駆動する方法を学びます。私たちは皆、JavaScriptとブラウザの関係を知っています。 JavaScriptは、フロントエンド開発のコア言語です。ブラウザで直接実行され、Webページが鮮明で興味深いものになります。なぜJavascrを疑問に思ったことがありますか

node.jsは、型を使用してストリーミングしますnode.jsは、型を使用してストリーミングしますApr 30, 2025 am 08:22 AM

node.jsは、主にストリームのおかげで、効率的なI/Oで優れています。 ストリームはデータを段階的に処理し、メモリの過負荷を回避します。大きなファイル、ネットワークタスク、リアルタイムアプリケーションの場合。ストリームとTypeScriptのタイプの安全性を組み合わせることで、パワーが作成されます

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衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

Eclipse を SAP NetWeaver アプリケーション サーバーと統合します。

mPDF

mPDF

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

メモ帳++7.3.1

メモ帳++7.3.1

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

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境