انتقل إلى المحتوى الرئيسي
شرح تطبيقي

كيف أستخدم Prisma ORM في بيئة الإنتاج: نصائح من مشاريع Next.js حقيقية

4 دقائق قراءة

استغرق تصحيح انحراف مخطط Prisma في تطبيق حجز سيارات ليموزين ٣ أيام وسط زحام رمضان.

prismanextjstypeormdevopsjavascript

في العام الماضي، أمضيت ثلاثة أسابيع في تصحيح خطأ في بيئة الإنتاج لمنصة حجز سيارات ليموزين فاخرة في أبوظبي، كانت تستمر في إرجاع استجابات فارغة للحجوزات الصحيحة للعملاء. لم يكن خطأ في React. ولم تكن مشكلة في إعدادات Firebase. تبين أن مخطط Prisma الخاص بنا كان لديه قيمة تعداد (enum) خارج الترتيب مقارنة بقاعدة البيانات الفعلية. انحراف مخطط كلاسيكي، ولكن في سياق عمل حقيقي - لم يتمكن الناس من حجز سيارات الليموزين خلال شهر رمضان، وهو في الأساس ذروة الموسم في الإمارات العربية المتحدة.

علمني ذلك بعض الدروس القاسية حول استخدام Prisma في تطبيقات Next.js. اسمحوا لي أن أشارككم الأجزاء الفوضوية - وليس فقط "استخدم TypeScript وستكون بخير" الهراء.


تصميم المخطط هو تفاوض مع الواقع

ما زلت أتذكر المرة الأولى التي قمت فيها بتحويل مشروع Laravel/MySQL كبير إلى Prisma. كان لدى العميل - وهو وكالة عقارية في دبي - 14 جدولًا بأنماط وراثة غريبة. اعتقدت بسذاجة أن "Prisma Studio سيتعامل مع الأمر"، ثم انتهى بي الأمر بتحرير schema.prisma يدويًا لمدة 36 ساعة متواصلة.

أحد الحيل التي تعلمتها: ضع قيم التعداد (enum) الخاصة بك بالضبط بالترتيب الذي تظهر به في قاعدة البيانات. يقوم Prisma بتعيين التعدادات الرقمية حسب موضع الفهرس عند استخدام التكوين الافتراضي. كان لدينا تعداد booking_status مع "confirmed" كقيمة ثانية في المخطط، لكن قاعدة البيانات خزنتها على أنها 0. هذا التطابق الضئيل جعل Prisma يعيد نتائج فارغة لنصف التطبيق أثناء استدعاءات Next.js API. استغرق الأمر مني يومين لاكتشاف ذلك لأن السجلات لم تظهر أي أخطاء - فقط ... ردود فارغة.

منذ ذلك الحين، أقوم بتشغيل npx prisma format بانتظام، ولكن أيضًا احتفظ بنسخة SQL خام في متناول يدي أثناء عمليات الترحيل. واجهة مستخدم Studio ليست دائمًا جديرة بالثقة عندما تكون لديك قواعد بيانات قديمة.


لا تثق أبدًا بالساعة

في الصيف الماضي، قمت ببناء تطبيق React Native/Next.js مدمج لتوصيل النباتات في الإمارات العربية المتحدة - Greeny Corner، موجود الآن على App Store. استخدمنا Prisma مع PlanetScale، والذي كان يعمل بشكل جيد في بيئة التطوير. ظهرت المشكلة بعد التشغيل الفعلي: استمر الفشل في التوسع التلقائي المستند إلى الوقت خلال عمليات الترحيل في منتصف الليل بسبب اختلافات التوقيت الصيفي بين الإمارات العربية المتحدة (لا يوجد توقيت صيفي) وخوادم PlanetScale في ولاية أوريغون.

كانت الأخطاء دائمًا في الساعة 12:01 صباحًا بالتوقيت العالمي المنسق +4 - ولهذا السبب لم يلاحظ أحد ذلك في البيئات التجريبية. تم إصلاح ذلك عن طريق تعيين process.env.TZ='UTC' بشكل صريح في next.config.js وكتابة SQL ترحيل خام للتعامل مع انتقالات المنطقة الزمنية. لا تذكر مستندات Prisma هذا، ولكن عندما يكون عملاؤك في دول مجلس التعاون الخليجي، فلا يمكنك تحمل انقطاعات منتصف الليل لأن قاعدة البيانات "أخذت قيلولة".


مآزق النشر

هذا هو الجزء الذي تتوقع فيه قائمة "أفضل 5 ممارسات". بدلاً من ذلك، إليك مشكلتا نشر حقيقيتين:

  1. لا تقم أبدًا بتشغيل prisma migrate push و prisma db push في نفس الوقت في CI/CD. أدى خط أنابيب بناء أحد العملاء إلى إتلاف مخطط قاعدة بيانات الإنتاج الخاص بهم لأن كلا الأمرين حاولا تغيير نفس الفهرس بالتوازي. استغرق الأمر مني أربع ساعات للتعافي من النسخة الاحتياطية. نقوم الآن بتأمين عمليات النشر باستخدام برنامج bash نصي بسيط يتحقق من عمليات الترحيل قيد التشغيل.
  1. اختبر دائمًا مدى تعقيد الاستعلام على شبكات الإمارات العربية المتحدة الفعلية. كان لدي تطبيق Next.js في الرياض يعيد 200 مللي ثانية TTFB محليًا، ولكن 1.2 ثانية في بيئة الإنتاج. لم تكن المشكلة في Vercel. اتضح أن عمق استعلام Prisma كان معقدًا للغاية بحيث لا يمكن لـ ISP المحلي للعميل تقييد عمليات بحث DNS. تم حله عن طريق إلغاء تسوية علاقة واحدة وإضافة إسقاط select بسيط في مسار API.

لماذا لا أستخدم Prisma Migrate في بعض المشاريع

بالنسبة إلى محرك الحجز الخاص بـ Tawasul Limo، تحولنا إلى عمليات ترحيل SQL الخام باستخدام Flyway لأن الشركة احتاجت إلى تغييرات DDL قابلة للتدقيق. كان لديهم مطلب قانوني لتتبع كل تغيير في المخطط للعقود الحكومية - وبصراحة، كنت خائفًا من تحذيرات "لا يمكن التراجع عن هذا الإجراء" في prisma migrate.

لذلك أنشأنا إعدادًا هجينًا:

  1. prisma generate لعميل TypeScript
  2. نصوص SQL يدوية لعمليات الترحيل
  3. مهمة cron تقوم بمقارنة schema.prisma بقاعدة البيانات ليلاً

يبدو الأمر متقطعًا، ولكنه يلبي احتياجات امتثال العميل دون إعادة اختراع ORM.


خدعة غريبة لن تجدها في البرامج التعليمية

تُظهر وثائق Prisma علاقات مثالية بين النماذج. في بيانات العملاء الحقيقيين، تنكسر الأشياء. بالنسبة لتطبيق توصيل الطعام في جدة، كان لدينا أكثر من 10000 مطعم مع إدخالات تحديد الموقع الجغرافي غير متناسقة. استمرت استدعاءات findMany الخاصة بـ Prisma في الانفجار بصمت في الترقيم بسبب قيم خطوط العرض الفارغة.

إصلاحنا؟ مكون إضافي مخصص للتحقق من النوع في prisma/schema.prisma:

prisma
model Location {
  @@schema.validateLatitude('lat') // Custom validation we wrote
}

يضيف هذا فحوصات وقت التشغيل قبل أن يرسل Prisma استعلام قاعدة البيانات. ليس في المستندات ولكنه أنقذنا مرتين أثناء عمليات ترحيل البيانات.


كل هذا يعني: Prisma رائع لتطبيقات Next.js حتى يبدأ في الفشل بهدوء بسبب الارتباك في المنطقة الزمنية أو انحراف التعداد. أستخدمه لكل مشروع الآن، ولكن كان عليّ أن أكافح خلال ما يكفي من أخطاء وقت متأخر من الليل لأعرف أن "جاهز للإنتاج" غالبًا ما يعني "يمكنك تصحيح الحالات الشاذة".

إذا كان أي من هذا يبدو مألوفًا - أو إذا كنت ترغب في مشاركة قصص الرعب الخاصة بك حول Prisma - فقل مرحبًا على sarahprofile.com/contact. أقوم بإعادة بناء تطبيق PHP قديم آخر إلى مجموعة Prisma/Next.js أثناء كتابة هذا. دعونا نعاني معا.


Frequently Asked Questions

How does Prisma compare to traditional ORMs like Eloquent (Laravel)?

Prisma offers stronger type safety and a more modern workflow, especially when combined with TypeScript. Eloquent is often simpler for rapid prototyping in PHP. Prisma also allows you to switch databases more easily compared to Eloquent.

Can I use Prisma with serverless functions (e.g., AWS Lambda, Cloudflare Workers)?

Yes, but you need to configure your serverless environment to maintain a persistent connection pool. Prisma’s connection management can be tricky in serverless environments without connection pooling. Vercel and Netlify offer easier integration.

What are the alternatives to Prisma for Next.js development?

TypeORM is a popular alternative, especially if you prefer decorators. Sequelize is another option, but it's more common in Javascript projects without Typescript. Drizzle ORM is also an up-and-coming option.


أسئلة متكررة

كيف تقارن Prisma بأنظمة ORM التقليدية مثل Eloquent (Laravel)؟

يوفر Prisma أمانًا أقوى للأنواع وسير عمل أكثر حداثة، خاصةً عند دمجه مع TypeScript. غالبًا ما يكون Eloquent أبسط للنماذج الأولية السريعة في PHP. يسمح لك Prisma أيضًا بتبديل قواعد البيانات بسهولة أكبر مقارنة بـ Eloquent.

هل يمكنني استخدام Prisma مع وظائف serverless (على سبيل المثال، AWS Lambda ، Cloudflare Workers)؟

نعم، ولكنك تحتاج إلى تهيئة بيئة serverless الخاصة بك للحفاظ على تجمع اتصال دائم. يمكن أن تكون إدارة اتصال Prisma صعبة في بيئات serverless بدون تجميع الاتصال. يوفر Vercel و Netlify تكاملًا أسهل.

ما هي بدائل Prisma لتطوير Next.js؟

TypeORM هو بديل شائع، خاصة إذا كنت تفضل أدوات التزيين (decorators). Sequelize هو خيار آخر، ولكنه أكثر شيوعًا في مشاريع Javascript بدون Typescript. Drizzle ORM هو أيضًا خيار واعد.

S

سارة

مطوّرة Full-Stack أولى ومعتمدة PMP — أبوظبي، الإمارات

أكثر من 7 سنوات في بناء تطبيقات ويب لشركات الإمارات والخليج. متخصصة في Laravel وNext.js وتطوير مواقع RTL العربية.

تعاون مع سارة