أدلة هندسية
استيراد بيانات CSV ذات مفاتيح أجنبية في PostgreSQL
حدّد معرّفات الوجهة المقابلة لمراجع المصدر دون تخمين. تعامل مع نطاق المستأجر، وغياب التطابقات، وترتيب الاستيراد، والعلاقات التي تقبل NULL أو تؤجَّل فحوصها.
حمّل قيم مراجع المصدر إلى منطقة التجهيز، وحدّد لكل منها مقابلًا باستخدام مفتاح وجهة معتمد، ولا تُدرج البيانات إلا بعد وجود تطابق واحد مسموح به بالضبط لكل مرجع مطلوب. يتحقق المفتاح الأجنبي من وجود المرجع في الوجهة. لكنه لا يستطيع تقرير أن «معرّف الشركة» القديم لدى العميل يعني الشيء نفسه الذي يعنيه المفتاح الأساسي للشركة في نظامك.
إذا كان الملف يحتوي بالفعل على معرّفات موثوقة للوجهة، فقد يكون حلّ المراجع بسيطًا. ومع ذلك، تحتاج إلى التحقق من انتماء المراجع إلى المستأجر المخوّل، ومن حق المشغّل في ربط السجلات بها. إذا كانت المعرّفات قد وُلّدت بصورة مستقلة في النظام القديم، فاحتفظ بها كمراجع خارجية بدلًا من نسخها إلى حقل المفتاح الأجنبي.
النطاق والافتراضات. PostgreSQL 17. تستخدم الأمثلة جداول مؤقتة ببيانات اصطناعية في جلسة واحدة.
اختر الهوية المستخدمة للمطابقة
افترض أن ملف تصدير العميل يحتوي على جهات اتصال وحقل company_ref بقيم مثل old-42. يعيّن جدول الشركات لديك معرّفًا مولّدًا خاصًا به. سيفشل استيراد old-42 إلى حقل معرّف الشركة الرقمي، لكن تحويل نوعه أو استبداله برقم اعتباطي سيكون أسوأ.
حدّد نطاق أسماء للمطابقة: المستأجر، والنظام المصدر، والمرجع الخارجي للشركة. خزّن خريطة خضعت للمراجعة من نطاق الأسماء هذا إلى معرّف الشركة في الوجهة، أو احصل على هذه الخريطة. اسم الشركة عادةً بديل ضعيف: فقد تتكرر الأسماء، أو تتغير، أو تختلف كتابتها. كذلك قد تتشارك عدة كيانات تجارية نطاق بريد إلكتروني واحدًا.
| التطابقات ضمن نطاق الأسماء المسموح به | المعنى | الإجراء |
|---|---|---|
| صفر | المرجع غير موجود أو القيمة المقدمة خاطئة | صحّح المرجع، أو أنشئ سجلًا أصليًا معتمدًا، أو سجّل استبعادًا |
| واحد | يوجد سجل مرشح فريد | تحقق من الصلاحية واستخدم معرّفه في الوجهة |
| أكثر من واحد | قاعدة الهوية ملتبسة | توقف واحسم نموذج الهوية؛ ولا تختر الأول |
«إنشاء سجل أصلي معتمد» عملية تتعلق بالعمل. قد تتطلب حقولًا غير موجودة في ملف جهات الاتصال، وقد تطلق آثارًا جانبية خاصة بها. لا تنشئ شركات صورية تلقائيًا لمجرد استيفاء قيد، إلا إذا كان ذلك قاعدة مقصودة في التطبيق.
حلّ مرجع خارجي ضمن نطاق المستأجر
يستخدم هذا الإعداد الكامل جداول مؤقتة في جلسة PostgreSQL 17 قابلة للتخلص منها. ويمثل مستأجرين لديهما المرجع الخارجي نفسه في نظام مصدر واحد.
CREATE TEMP TABLE import_companies_demo (
id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
tenant_id integer NOT NULL,
source_system text NOT NULL,
external_ref text NOT NULL,
UNIQUE (tenant_id, source_system, external_ref),
UNIQUE (tenant_id, id)
);
INSERT INTO import_companies_demo
(tenant_id, source_system, external_ref)
VALUES (10, 'legacy-crm', 'old-42'),
(20, 'legacy-crm', 'old-42');
CREATE TEMP TABLE import_contacts_stage (
source_record integer PRIMARY KEY,
email text NOT NULL,
company_ref text NOT NULL
);
INSERT INTO import_contacts_stage VALUES
(1, 'first@example.test', 'old-42'),
(2, 'second@example.test', 'missing-99');المستأجر المخوّل لعملية الاستيراد هو 10، والنظام المصدر المعتمد هو legacy-crm. هاتان قيمتان موثوقتان من مدخلات المهمة في تنفيذ فعلي؛ وهما ثابتان في هذا المثال. تحقق من حلّ المراجع قبل إدراج جهات الاتصال:
SELECT stage.source_record, stage.company_ref,
count(company.id) AS matches
FROM import_contacts_stage AS stage
LEFT JOIN import_companies_demo AS company
ON company.tenant_id = 10
AND company.source_system = 'legacy-crm'
AND company.external_ref = stage.company_ref
GROUP BY stage.source_record, stage.company_ref
HAVING count(company.id) <> 1
ORDER BY stage.source_record;تحدد النتيجة أن السجل 2 لا يملك أي تطابق. يمنع قيد التفرد على نطاق أسماء الشركة وجود عدة تطابقات في هذا المخطط. وإذا كانت الوجهة الفعلية تفتقر إلى ذلك القيد، فيمكن للفحص التشخيصي نفسه كشف التباس يجب تصحيحه قبل الوثوق بقاعدة مطابقة فريدة.
سيُسقط الربط الداخلي وحده السجل 2 بصمت. وقد يبدو ناتجه كاستيراد ناجح لجهة اتصال واحدة. يجعل الفحص التشخيصي الصريح الاستبعاد قرارًا، بدلًا من أن يكون أثرًا جانبيًا غير مقصود لأوامر SQL.
أبقِ علاقة المستأجر ضمن القيد
في هذا الاختبار المسبق، افترض أن مالك البيانات يعتمد تصحيح السجل 2 إلى old-42. هذا تصحيح لبيانات اصطناعية، وليس حلًا احتياطيًا عامًا للمراجع المفقودة. الكتلة التالية اختبار مسبق ينتهي بالتراجع فقط؛ فاستخدم نتيجة SELECT فيها لفحص السجلات بعد حلّ مراجعها.
BEGIN;
UPDATE import_contacts_stage
SET company_ref = 'old-42'
WHERE source_record = 2;
CREATE TEMP TABLE import_contacts_target (
tenant_id integer NOT NULL,
source_record integer NOT NULL,
email text NOT NULL,
company_id bigint NOT NULL,
PRIMARY KEY (tenant_id, source_record),
FOREIGN KEY (tenant_id, company_id)
REFERENCES import_companies_demo (tenant_id, id)
);
INSERT INTO import_contacts_target
(tenant_id, source_record, email, company_id)
SELECT 10, stage.source_record, stage.email,
(SELECT company.id
FROM import_companies_demo AS company
WHERE company.tenant_id = 10
AND company.source_system = 'legacy-crm'
AND company.external_ref = stage.company_ref)
FROM import_contacts_stage AS stage;
SELECT * FROM import_contacts_target ORDER BY source_record;
ROLLBACK;يُربط السجلان بالشركة التابعة للمستأجر 10. ينتج الاستعلام الفرعي ذو القيمة المفردة NULL عند عدم وجود تطابق، فترفضها الوجهة عبر NOT NULL. أما وجود عدة تطابقات فيؤدي إلى فشل الاستعلام الفرعي ذي القيمة المفردة. يتجنب ذلك فقدان الصفوف الصامت الناتج عن الربط الداخلي.
يتحقق المفتاح الأجنبي المركب من وجود زوج المستأجر ومعرّف الشركة معًا. أما المفتاح الأجنبي على معرّف الشركة وحده فلا يثبت إلا وجودها على مستوى النظام كله، ولا يثبت اتساق المستأجر. يستخدم المفتاح الأساسي هنا رقم سجل المصدر لغرض العرض؛ وتحتاج أداة استيراد قابلة لإعادة الاستخدام إلى نطاق أسماء للاستيراد أو المهمة، أو هوية عمل ثابتة ومعتمدة، للتمييز بين الملفات المنفصلة.
يظل تخويل التطبيق وRLS ضروريين حيث يعتمد عليهما التطبيق. سلامة المراجع ليست نظامًا كاملًا للتحكم في الوصول.
استورد السجلات الأصلية أولًا واحتفظ بخريطة المعرّفات
عند استيراد السجلات الأصلية والتابعة معًا، وفّر هويات السجلات الأصلية أولًا. أدرج مجموعة السجلات الأصلية المعتمدة، والتقط خريطة المعرّفات الناتجة أو حدّدها، ثم حوّل مراجع السجلات التابعة باستخدام تلك الخريطة. أبقِ نطاق الأسماء محصورًا بالمستأجر ومرتبطًا بالنظام المصدر.
لا تفترض أن المعرّفات المولّدة متتالية، أو تطابق ترتيب صفوف CSV، أو يمكن إعادة بنائها من أول معرّف مُعاد بإضافة إزاحة. تكسر المعاملات المتزامنة، والمحاولات الفاشلة، وسلوك المتتاليات هذه الافتراضات. استخدم ربطًا صريحًا بين كل مفتاح ومعرّفه.
يمكن لبرنامج نصي لمرة واحدة الاحتفاظ بخريطة خضعت للمراجعة داخل معاملة عندما تكون مجموعة البيانات صغيرة. أما الترحيل القابل للاستئناف فيحتاج إلى أدلة ربط محفوظة بشكل دائم تبقى بعد إعادة تشغيل العملية وتمنع إعادة المحاولة من إنشاء سجل أصلي ثانٍ. ينبغي أن تعكس سياسة الاحتفاظ بها والوصول إليها بيانات المصدر التي تحتويها.
إذا احتوى المصدر على عدة تمثيلات للسجل الأصلي نفسه، فحدّد كيفية إزالة تكراراتها قبل إنشاء السجلات التابعة. هنا قد يتوسع الترحيل ليتجاوز استيراد جدول واحد. يغطي دليل أعمدة الهوية والقيم الافتراضية قواعد تقديم المعرّفات بصورة منفصلة.
العلاقات التي تقبل NULL أو تُستكمل في مرور ثانٍ أو تؤجَّل فحوصها
قد يعني المفتاح الأجنبي الذي يقبل NULL، على نحو مشروع، «لم تُعيّن شركة». ويجب ألا يعني بصمت «تعذر العثور على الشركة المقدمة». حافظ على الفصل بين النتيجتين في مراجعة المصدر وفي النتيجة النهائية.
يمكن لمرور ثانٍ ملء مرجع بعد وجود الصفين، لكن فقط حين تسمح الوجهة بقيمة NULL المؤقتة ويستطيع التطبيق تحملها. إذا ثُبّت كل مرور على حدة، فستكون الحالة الوسيطة مرئية وقد تُطلق تدفقات عمل. وإذا كان المروران في معاملة واحدة، فتصبح حالة قاعدة البيانات مرئية معًا عند التثبيت، لكن يظل عليك فهم المشغلات والآثار الخارجية.
يمكن لمفتاح أجنبي قابل لتأجيل الفحص إرجاء فحصه إلى وقت لاحق في المعاملة نفسها. لكنه لا ينشئ صفًا مرجعيًا مفقودًا، ولا يجعل العمود يقبل NULL، ولا يسمح ببقاء مخالفة عند التثبيت. لا يمكن تأجيل توقيت الفحص إلا للقيود المعلنة DEFERRABLE؛ ولا تؤجَّل قيود NOT NULL وCHECK بهذه الطريقة في PostgreSQL 17. راجع SET CONSTRAINTS.
تحتاج العلاقات الدائرية إلى مخطط محدد وخطة معاملات محددة. قد تشمل الخيارات حالات صحيحة تقبل NULL، أو مراجع مؤجَّلة الفحص، أو إعادة تصميم على مستوى مجال العمل. تعطيل المفاتيح الأجنبية ليس إجراءً عامًا للتعافي. اختبر الاستراتيجية المختارة وفق الثوابت الفعلية التي يجب أن يحافظ عليها التطبيق.
تحقق من العلاقة بعد الاستيراد
تحقق من معرفة مصير كل سجل مصدر مقبول، ومن تطابق مرجعه المحلول مع خريطة الربط التي خضعت للمراجعة. احسب السجلات المفقودة بصورة منفصلة عن السجلات المرتبطة بسجل أصلي خاطئ. فقد تفرض قاعدة البيانات مرجعًا صحيحًا بينما تختار أداة الاستيراد شركة صحيحة الوجود لكنها غير المقصودة.
قد تصبح نتائج البحث المسبق قديمة. أبقِ القيود النهائية، ونفّذ الربط والكتابة باستراتيجية معاملات مناسبة. حدّد كيفية التعامل مع حذف سجل أصلي، أو إعادة تعيين مرجع، أو استيراد متنافس. في ترحيل مضبوط لمرة واحدة، قد يكون تنسيق نافذة الكتابة أبسط من بناء خدمة ترحيل متزامنة.
استخدم فحوص التحقق بعد الاستيراد لمقارنة الهويات المقبولة والحقول المهمة، ثم اختبر طرق عرض العلاقات المعتادة في التطبيق.