> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-vortex-format.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# استخدام Drizzle ORM مع ClickHouse Managed Postgres

> اربط تطبيق TypeScript بخدمة ClickHouse Managed Postgres باستخدام Drizzle ORM وnode-postgres، ونفّذ عمليات الترحيل باستخدام drizzle-kit، ثم نفّذ الاستعلامات عبر اتصال TLS مُتحقَّق منه

export const BetaBadge = ({link, galaxyTrack, galaxyEvent}) => {
  if (link) {
    return <a href={link} target="_blank" rel="noopener noreferrer" className="betaBadge" onClick={galaxyTrack && galaxyEvent ? galaxyOnClick(galaxyEvent) : undefined}>
                <span>Beta</span>
            </a>;
  }
  return <a href="https://clickhouse.com/docs/reference/settings/beta-and-experimental-features#beta-features" className="betaBadge">
            <span>ميزة Beta</span>
        </a>;
};

<BetaBadge link="https://clickhouse.com/cloud/postgres" galaxyTrack={true} galaxyEvent="docs.managed-postgres.guides-drizzle-beta" />

[Drizzle ORM](https://orm.drizzle.team/) هي أداة ربط الكائنات بقواعد البيانات مكتوبة بلغة TypeScript، وتوفّر أداة لبناء الاستعلامات بصيغة قريبة من SQL، في حين أن `drizzle-kit` هي واجهة سطر الأوامر المصاحبة لها، وتُستخدم لتوليد عمليات الترحيل وتنفيذها. في هذا الدليل، ستُعرّف جدول `todos` بلغة TypeScript، ثم تنشئه عبر عملية ترحيل باستخدام `drizzle-kit`، وبعد ذلك تعالج استعلامات الإنشاء والقراءة والتحديث والحذف من خلال خادم HTTP صغير مبني على Node.js. ويعتمد كل اتصال على بروتوكول TLS مع التحقق الكامل من الشهادة.

<h2 id="prerequisites">
  المتطلبات الأساسية
</h2>

* [Node.js](https://nodejs.org/) الإصدار 20 أو أحدث
* حساب ClickHouse Cloud
* [`psql`](https://www.postgresql.org/download/) لإنشاء قاعدة البيانات. ويمكنك أيضًا تنفيذ عبارة `CREATE DATABASE` في [SQL console](/ar/integrations/connectors/sql-clients/sql-console).

<h2 id="create-service">
  إنشاء خدمة ClickHouse Managed Postgres
</h2>

في وحدة تحكم ClickHouse Cloud، انقر على **New service** ثم اختر **Postgres**. سيصبح المثيل جاهزًا في غضون دقائق قليلة. للاطلاع على شرح تفصيلي للخطوات، راجع [دليل البدء السريع](/ar/products/managed-postgres/quickstart).

<h2 id="connection-details">
  الحصول على بيانات الاتصال
</h2>

انقر على **Connect** في الشريط الجانبي الأيسر لخدمتك. تعرض النافذة المنبثقة اسم المستخدم وكلمة المرور والخادم والمنفذ، وتتضمّن مفتاح تبديل **Directly** / **via PgBouncer**.

يستخدم هذا الدليل سلسلتي اتصال:

* **الاتصال المباشر (المنفذ `5432`)** لأداة `drizzle-kit`. تنفّذ عمليات الترحيل أوامر DDL، وقد يطول تنفيذها، وقد تعتمد على حالة الجلسة مثل `SET lock_timeout`، لذا ينبغي أن تتصل بـ Postgres مباشرةً.
* **PgBouncer (المنفذ `6432`)** للتطبيق. يعمل [PgBouncer](/ar/products/managed-postgres/connection#pgbouncer) المضمَّن في وضع تجميع المعاملات، ويتيح لعدد كبير من مثيلات التطبيق، بما فيها الدوال بلا خادم، أن تتشارك عددًا محدودًا من اتصالات Postgres.

<Tip>
  إذا كنت تشغّل خادم Node.js واحدًا يعمل لفترات طويلة، فإن `node-postgres` يدير مجمّع اتصالات خاصًا به، لذا يمكنك أيضًا توجيه التطبيق إلى الاتصال المباشر. استخدم اتصال PgBouncer عند التوسّع أفقيًا إلى عدد كبير من العمليات أو عند التشغيل على منصات بلا خادم.
</Tip>

بعد تحديد **Directly**، فعّل **Use SSL**. سينتهي عنوان URL الخاص بالاتصال في تبويب **url** عندئذٍ بـ `sslmode=verify-full&sslrootcert=<service-name>-ca-certificate.pem`، ويكون المنفذ `5432`. حدّد **via PgBouncer** لعرض بيانات الاتصال عبر المجمّع: يتغيّر المنفذ إلى `6432`، ويتضمّن عنوان URL دائمًا `sslmode=verify-full`.

في النافذة المنبثقة، انقر على **Download CA certificate**. يمكنك أيضًا تنزيلها من **Settings → CA Certificate**. هذه الشهادة خاصة بمثيلك وحده، لذا يمكن للمشغّل استخدامها للتحقق من أنه يتصل بخادمك فعلًا.

<h2 id="project-setup">
  إعداد المشروع
</h2>

أنشئ مشروعًا، ثم ثبّت Drizzle ORM ومشغّل [`node-postgres`](https://node-postgres.com/) ‏(`pg`) و`drizzle-kit`:

```bash theme={null}
mkdir drizzle-managed-postgres && cd drizzle-managed-postgres
npm init -y
npm pkg set type=module
npm install drizzle-orm pg dotenv
npm install -D drizzle-kit tsx @types/pg
```

<Tip>
  **هل تُضيف ذلك إلى تطبيق قائم؟**

  تخطَّ الأوامر `mkdir` و`npm init` و`npm pkg set type=module`. بدلاً من ذلك، شغّل في مشروعك الأمرين `npm install drizzle-orm pg dotenv` و`npm install -D drizzle-kit tsx @types/pg`، ثم انتقل إلى قسم [تهيئة الاتصال](#configure-connection).
</Tip>

<h2 id="configure-connection">
  تهيئة الاتصال
</h2>

انقل شهادة CA التي نزّلتها إلى دليل المشروع، ثم أعد تسميتها إلى `ca-certificate.pem`.

أنشئ قاعدة بيانات للتطبيق. استبدل `<PASSWORD>` والمضيف بالقيم الظاهرة في النافذة المنبثقة **Connect**:

```bash theme={null}
psql "postgresql://postgres:<PASSWORD>@your-instance.pg.clickhouse.cloud:5432/postgres?sslmode=verify-full&sslrootcert=ca-certificate.pem" -c "CREATE DATABASE guide_drizzle;"
```

```text theme={null}
CREATE DATABASE
```

أضف سلسلتَي الاتصال كلتيهما إلى ملف `.env` في المجلد الجذر للمشروع، أو إلى ملف `.env` الموجود لديك مسبقًا. ولا تختلف السلسلتان إلا في رقم المنفذ، وكلتاهما تشيران إلى قاعدة البيانات `guide_drizzle`:

```bash title=".env" theme={null}
# Runtime queries go through PgBouncer (port 6432)
DATABASE_URL="postgresql://postgres:<PASSWORD>@your-instance.pg.clickhouse.cloud:6432/guide_drizzle?sslmode=verify-full&sslrootcert=ca-certificate.pem"
# drizzle-kit migrations connect directly to Postgres (port 5432)
DIRECT_DATABASE_URL="postgresql://postgres:<PASSWORD>@your-instance.pg.clickhouse.cloud:5432/guide_drizzle?sslmode=verify-full&sslrootcert=ca-certificate.pem"
```

تقرأ مكتبة `node-postgres` القيمتين `sslmode=verify-full` و`sslrootcert` من عنوان URL، ثم تحمّل ملف CA وتتحقق من سلسلة الشهادات ومن اسم المضيف معًا، فلا حاجة إلى كتابة أي شيفرة TLS إضافية. يُحدَّد مسار `sslrootcert` نسبةً إلى الدليل الذي تشغّل الأوامر منه. واحرص على إبقاء الملف `.env` خارج نظام التحكم في الإصدارات.

<Note>
  إذا كان ملف CA مفقودًا أو غير صحيح، يفشل الاتصال ويظهر الخطأ `unable to verify the first certificate`. وإذا لم يطابق اسم المضيف الشهادة، يفشل الاتصال ويظهر الخطأ `ERR_TLS_CERT_ALTNAME_INVALID`. وإذا احتوت كلمة المرور على محارف خاصة مثل `@` أو `/` أو `#`، فرمّزها بترميز URL.
</Note>

<h2 id="schema">
  تعريف المخطط
</h2>

أنشئ الملف `src/db/schema.ts`:

```ts title="src/db/schema.ts" theme={null}
import { boolean, integer, pgTable, text, timestamp } from "drizzle-orm/pg-core";

export const todos = pgTable("todos", {
  id: integer().primaryKey().generatedAlwaysAsIdentity(),
  title: text().notNull(),
  done: boolean().notNull().default(false),
  createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
});
```

أنشئ الملف `drizzle.config.ts` في المجلد الجذر للمشروع. يوجّه هذا الملف أداة `drizzle-kit` إلى المخطط وإلى الاتصال المباشر:

```ts title="drizzle.config.ts" theme={null}
import "dotenv/config";
import { defineConfig } from "drizzle-kit";

export default defineConfig({
  dialect: "postgresql",
  schema: "./src/db/schema.ts",
  out: "./drizzle",
  dbCredentials: {
    // Migrations use the direct connection (port 5432)
    url: process.env.DIRECT_DATABASE_URL!,
  },
});
```

<h2 id="migrations">
  تشغيل عمليات الترحيل
</h2>

أنشئ ترحيل SQL انطلاقًا من المخطط:

```bash theme={null}
npx drizzle-kit generate --name init
```

```text theme={null}
1 tables
todos 4 columns 0 indexes 0 fks

[✓] Your SQL migration file ➜ drizzle/0000_init.sql 🚀
```

يحتوي الملف المُنشأ `drizzle/0000_init.sql` على عبارة `CREATE TABLE`. راجِعه، ثم ثبّت (commit) المجلد `drizzle` مع شيفرتك. بعد ذلك، طبّقه:

```bash theme={null}
npx drizzle-kit migrate
```

```text theme={null}
Using 'pg' driver for database querying
[✓] migrations applied successfully!
```

يسجّل `drizzle-kit migrate` عمليات الترحيل المُطبَّقة في جدول `drizzle.__drizzle_migrations`، ولا ينفّذ في الاستدعاءات اللاحقة سوى عمليات الترحيل الجديدة. وكلما غيّرت `schema.ts`، شغّل `generate` ثم `migrate` من جديد.

<Tip>
  ينتهي `drizzle-kit migrate` برمز الحالة `1` ومن دون أي رسالة error عندما يتعذّر عليه الاتصال، كأن يكون مسار `sslrootcert` أو كلمة المرور غير صحيحين. في هذه الحالة، اختبر `DIRECT_DATABASE_URL` أولًا باستخدام `psql`.
</Tip>

يطبّق `drizzle-kit push` تغييرات المخطط من دون ملفات ترحيل. وهو مفيد عند إعداد النماذج الأولية، أما في بيئة الإنتاج فيوفّر لك `generate` و`migrate` ملفات SQL قابلة للمراجعة وسجلًا بالتغييرات.

<h2 id="query">
  الاستعلام من قاعدة البيانات
</h2>

أنشئ الملف `src/db/index.ts`، الذي يُنشئ عميل Drizzle عبر مجمّع اتصالات `node-postgres` باستخدام اتصال PgBouncer:

```ts title="src/db/index.ts" theme={null}
import "dotenv/config";
import { drizzle } from "drizzle-orm/node-postgres";

// The app uses the PgBouncer connection (port 6432)
export const db = drizzle(process.env.DATABASE_URL!);
```

أنشئ الملف `src/server.ts`، وهو خادم HTTP صغير يُنفّذ استعلام Drizzle واحدًا لكل مسار. أما إن كان لديك تطبيق قائم، فيمكنك بدلًا من ذلك استدعاء استعلامات `db` نفسها من معالجات المسارات في تطبيقك:

```ts title="src/server.ts" theme={null}
import { createServer } from "node:http";
import { desc, eq, not } from "drizzle-orm";
import { db } from "./db";
import { todos } from "./db/schema";

const server = createServer(async (req, res) => {
  const url = new URL(req.url ?? "/", "http://localhost");
  const id = Number(url.pathname.split("/")[2]);
  let body: unknown;

  try {
    if (req.method === "GET" && url.pathname === "/todos") {
      // Read
      body = await db.select().from(todos).orderBy(desc(todos.id));
    } else if (req.method === "POST" && url.pathname === "/todos") {
      // Create
      const title = url.searchParams.get("title") ?? "Untitled";
      [body] = await db.insert(todos).values({ title }).returning();
    } else if (req.method === "PATCH" && id) {
      // Update: toggle the done flag
      [body] = await db
        .update(todos)
        .set({ done: not(todos.done) })
        .where(eq(todos.id, id))
        .returning();
    } else if (req.method === "DELETE" && id) {
      // Delete
      [body] = await db.delete(todos).where(eq(todos.id, id)).returning();
    } else {
      res.writeHead(404).end();
      return;
    }
    res.writeHead(200, { "Content-Type": "application/json" });
    res.end(JSON.stringify(body, null, 2) + "\n");
  } catch (err) {
    console.error(err);
    res.writeHead(500).end("Database error\n");
  }
});

server.listen(3101, () => console.log("Listening on http://localhost:3101/todos"));
```

<Note>
  لا حاجة إلى أي إعدادات للمشغّل عند استخدام PgBouncer. تستخدم استعلامات Drizzle عبارات غير مسمّاة افتراضيًا، كما يدعم PgBouncer المضمَّن العبارات المُعدّة مسبقًا المسمّاة أيضًا، مثل تلك التي تُنشأ باستخدام `.prepare` في Drizzle، وذلك في وضع تجميع المعاملات. أما الميزات المرتبطة بمستوى الـ session، مثل `LISTEN` والأقفال الاستشارية على مستوى الـ session، فلا تعمل عبر PgBouncer. راجع [الأسئلة الشائعة](/ar/products/managed-postgres/faq#prepared-statement-errors).
</Note>

<h2 id="verify">
  التشغيل والتحقق
</h2>

شغّل الخادم:

```bash theme={null}
npx tsx src/server.ts
```

```text theme={null}
Listening on http://localhost:3101/todos
```

في طرفية ثانية، أنشئ مهمتين، ثم حدِّد الأولى على أنها مكتملة، واحذف الثانية:

```bash theme={null}
curl -X POST "http://localhost:3101/todos?title=Try%20Drizzle%20ORM"
curl -X POST "http://localhost:3101/todos?title=Write%20a%20migration"
curl -X PATCH http://localhost:3101/todos/1
curl -X DELETE http://localhost:3101/todos/2
```

يُرجِع طلب `PATCH` الصفَّ المُحدَّث:

```json theme={null}
{
  "id": 1,
  "title": "Try Drizzle ORM",
  "done": true,
  "createdAt": "2026-09-30T16:45:14.610Z"
}
```

افتح `http://localhost:3101/todos` في متصفحك لعرض المهام المتبقية. ستظهر الاستجابة على النحو التالي:

```json theme={null}
[
  {
    "id": 1,
    "title": "Try Drizzle ORM",
    "done": true,
    "createdAt": "2026-09-30T16:45:14.610Z"
  }
]
```

لعرض البيانات في وحدة التحكم، افتح **SQL console** من الشريط الجانبي الأيسر لخدمتك، ثم وسّع `guide_drizzle` ثم `public`، وانقر على جدول `todos`. يحتوي المخطط `drizzle` على جدول سجل عمليات الترحيل. ويضم الجدول الصف المتبقي:

| id | title | done | created\_at |
| - | - | - | - |
| 1 | Try Drizzle ORM | true | 2026-09-30 16:45:14.610099+00 |

<h2 id="next-steps">
  الخطوات التالية
</h2>

* [الاتصال](/ar/products/managed-postgres/connection): سلاسل الاتصال وPgBouncer وTLS
* [الإعدادات](/ar/products/managed-postgres/settings): معلمات Postgres وPgBouncer، مثل `max_connections`
* [النسخ المتماثلة للقراءة](/ar/products/managed-postgres/read-replicas): توسيع نطاق عمليات القراءة باستخدام الدالة [`withReplicas`](https://orm.drizzle.team/docs/read-replicas) في Drizzle
* [الأمان](/ar/products/managed-postgres/security): قوائم التحكم في الوصول حسب عناوين IP والشبكات الخاصة
