ProHoster > بلوق > إدارة > Magento 2: استيراد المنتجات مباشرة إلى قاعدة البيانات
Magento 2: استيراد المنتجات مباشرة إلى قاعدة البيانات
В المادة السابقة لقد وصفت عملية استيراد المنتجات إلى Magento 2 بالطريقة المعتادة - من خلال النماذج والمستودعات. تتميز الطريقة التقليدية بسرعة معالجة بيانات منخفضة للغاية. على جهاز الكمبيوتر المحمول الخاص بي، كان المنتج حوالي منتج واحد في الثانية. في هذا الاستمرار، أفكر في طريقة بديلة لاستيراد منتج - عن طريق الكتابة المباشرة إلى قاعدة البيانات، وتجاوز آليات Magento 2 القياسية (النماذج، المصانع، المستودعات). يمكن تكييف تسلسل خطوات استيراد المنتجات مع أي لغة برمجة يمكنها العمل مع MySQL.
إخلاء المسئولية: لدى Magento وظائف جاهزة لـ استيراد البيانات وعلى الأرجح سيكون لديك ما يكفي منه. ومع ذلك، إذا كنت بحاجة إلى مزيد من التحكم في عملية الاستيراد، وليس مقتصرًا على إعداد ملف CSV لما هو موجود، فمرحبًا بك ضمن cat.
يمكن الاطلاع على الكود الناتج عن كتابة المقالتين في وحدة ماجنتو "lancer32/mage2_ext_demo_import". فيما يلي بعض القيود التي اتبعتها لتبسيط كود الوحدة التجريبية:
يتم إنشاء المنتجات فقط، ولا يتم تحديثها.
مستودع واحد
يتم استيراد أسماء الفئات فقط، بدون بنيتها
تتوافق هياكل البيانات مع الإصدار 2.3
JSON لاستيراد منتج واحد:
{
"sku": "MVA20D-UBV-3",
"name": "Заглушка для пломбировки ВА47-29 IEK",
"desc": "Обеспечение доступа к устройствам ...",
"desc_short": "Заглушка для пломбировки ВА47-29 IEK предназначена для ...",
"price": 5.00,
"qty": 25,
"categories": ["Категория 1", "Категория 2"],
"image_path": "mva20d_ubv_3.png"
}
نظرة عامة على خطوات الاستيراد الرئيسية
تسجيل المنتج نفسه
رابط المنتج والموقع
سمات المنتج الأساسية (EAV)
بيانات المخزون (كمية المنتج في المخزون)
وسائط (صور)
الارتباط مع فئات الكتالوج
تسجيل المنتج
معلومات المنتج الأساسية موجودة catalog_product_entity:
CREATE TABLE `catalog_product_entity` (
`entity_id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Entity Id',
`attribute_set_id` smallint(5) unsigned NOT NULL DEFAULT '0' COMMENT 'Attribute Set ID',
`type_id` varchar(32) NOT NULL DEFAULT 'simple' COMMENT 'Type ID',
`sku` varchar(64) DEFAULT NULL COMMENT 'SKU',
`has_options` smallint(6) NOT NULL DEFAULT '0' COMMENT 'Has Options',
`required_options` smallint(5) unsigned NOT NULL DEFAULT '0' COMMENT 'Required Options',
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'Creation Time',
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'Update Time',
PRIMARY KEY (`entity_id`),
KEY `CATALOG_PRODUCT_ENTITY_ATTRIBUTE_SET_ID` (`attribute_set_id`),
KEY `CATALOG_PRODUCT_ENTITY_SKU` (`sku`)
)
الحد الأدنى من المعلومات المطلوبة لإنشاء إدخال في سجل المنتج:
attribute_set_id
sku
إضافي:
type_id - إذا لم يتم تحديده، فسيتم استخدام "بسيط".
للكتابة المباشرة إلى قاعدة البيانات، أستخدم محول قاعدة البيانات الخاص بـ Magento نفسه:
المنتج المسجل حديثًا ليس له اسم أو وصف بعد. كل هذا يتم من خلال سمات إيف. فيما يلي قائمة بسمات المنتج الأساسية اللازمة لعرض المنتج بشكل صحيح في المقدمة:
name
price
description
short_description
status
tax_class_id
url_key
visibility
تتم إضافة سمة منفصلة إلى المنتج مثل هذا (يتم حذف تفاصيل الحصول على المعرف ونوع السمة من خلال الكود الخاص بها):
public function create($prodId, $attrCode, $attrValue)
{
$attrId = /* get attribute ID by attribute code */
$attrType = /* get attribute type [datetime|decimal|int|text|varchar]) by attribute code */
if ($attrId) {
/** @var MagentoFrameworkAppResourceConnection $this->resource */
/** @var MagentoFrameworkDBAdapterPdoMysql $conn */
$conn = $this->resource->getConnection();
$tblName = 'catalog_product_entity_' . $attrType;
$table = $this->resource->getTableName($tblName);
$bind = [
'attribute_id' => $attrId,
'entity_id' => $prodId,
/* put all attributes to default store view with id=0 (admin) */
'store_id' => 0,
'value' => $attrValue
];
$conn->insert($table, $bind);
}
}
من خلال رمز السمة نحدد معرفها ونوع بياناتها (datetime, decimal, int, text, varchar)، ثم اكتب بيانات واجهة المتجر الإدارية في الجدول المناسب (store_id = 0).
بعد إضافة السمات السابقة للمنتج، نحصل على الصورة التالية في لوحة الإدارة:
بيانات المخزون
بدءًا من الإصدار 2.3 في Magento، هناك مجموعتان من الجداول المتوازية التي تخزن معلومات المخزون (كمية المنتج):
cataloginventory_*: الهيكل القديم
inventory_*: الهيكل الجديد (MSI - المخزون متعدد المصادر)؛
تحتاج إلى إضافة بيانات المخزون إلى كلا الهيكلين، لأن الهيكل الجديد ليس مستقلاً تمامًا عن الهيكل القديم (من المحتمل جدًا أن يكون ذلك ل default يستخدم المستودع في الهيكل الجديد جدولاً cataloginventory_stock_status كما inventory_stock_1).
جرد الكتالوج _
عند نشر Magneto 2.3، لدينا في البداية إدخالان store_websiteوالذي يتوافق مع موقعين - العميل الإداري والرئيسي:
أي أنه ليس لدينا سوى "مخزن" واحد في الهيكل القديم (stock) وهو مرتبط بالموقع الإداري. إضافة جديدة عن طريق المشرف sources/stocks في MSI (البنية الجديدة) لا يؤدي إلى إدخالات جديدة في cataloginventory_stock.
تتم كتابة بيانات المخزون حول المنتجات في الهيكل القديم في البداية في الجداول:
cataloginventory_stock_item
cataloginventory_stock_status
كتالوج مخزون_stock_item
function createOldItem($prodId, $qty)
{
$isQtyDecimal = (((int)$qty) != $qty);
$isInStock = ($qty > 0);
/** @var MagentoFrameworkAppResourceConnection $this->resource */
/** @var MagentoFrameworkDBAdapterPdoMysql $conn */
$conn = $this->resource->getConnection();
$table = $this->resource->getTableName('cataloginventory_stock_item');
$bind = [
'product_id' => $prodId,
/* we use one only stock in 'cataloginventory' structure by default */
'stock_id' => 1,
'qty' => $qty,
'is_qty_decimal' => $isQtyDecimal,
'is_in_stock' => $isInStock,
/* default stock is bound to admin website (see `cataloginventory_stock`) */
'website_id' => 0
];
$conn->insert($table, $bind);
}
كتالوج مخزون_المخزون_حالة
function createOldStatus($prodId, $qty)
{
$isInStock = ($qty > 0);
/** @var MagentoFrameworkAppResourceConnection $this->resource */
/** @var MagentoFrameworkDBAdapterPdoMysql $conn */
$conn = $this->resource->getConnection();
$table = $this->resource->getTableName('cataloginventory_stock_status');
$bind = [
'product_id' => $prodId,
/* we use one only stock in 'cataloginventory' structure by default */
'stock_id' => 1,
'qty' => $qty,
'stock_status' => MagentoCatalogInventoryApiDataStockStatusInterface::STATUS_IN_STOCK,
/* default stock is bound to admin website (see `cataloginventory_stock`) */
'website_id' => 0
];
$conn->insert($table, $bind);
}
جرد_
في البداية، يحتوي الهيكل الجديد لتخزين بيانات المخزون على 1 "مصدر"(inventory_source):
«مصدر' يمثل التخزين الفعلي للمنتجات (يحتوي الإدخال على الإحداثيات الفعلية والعنوان البريدي). "مستودع" هو اتحاد منطقي لعدة "مصادر" (inventory_source_stock_link)
على المستوى الذي يتم فيه الارتباط بقناة المبيعات (inventory_stock_sales_channel)
type |code|stock_id|
-------|----|--------|
website|base| 1|
انطلاقًا من بنية البيانات، يُفترض وجود أنواع مختلفة من قنوات البيع، ولكن بشكل افتراضي العلاقة فقط "مخزون"-"موقع الكتروني» (رابط الموقع يتبع كود الموقع — base).
واحد "مستودع» يمكن ربطها بعدة «مصادر"و واحد"مصدر" - للعديد "المستودعات"(علاقة متعدد إلى متعدد). الاستثناءات هي الافتراضيةمصدر"و"مستودع". لا يتم إعادة ربطها بالكيانات الأخرى (القيود على مستوى الكود - الخطأ "لا يمكن حفظ الرابط المتعلق بالمصدر الافتراضي أو المخزون الافتراضي"). يمكنك قراءة المزيد عن بنية MSI في Magento 2 في المقالة "نظام إدارة المستودعات باستخدام CQRS ومصادر الأحداث. تصميم".
سأستخدم التكوين الافتراضي وأضيف جميع معلومات المخزون إلى المصدر defaultوالتي تشارك في قناة المبيعات المرتبطة بالموقع الإلكتروني بالكود base (يتوافق مع جزء العميل من المتجر - انظر store_website):
بعد إضافة بيانات المخزون للمنتج في لوحة الإدارة يتم الحصول على الصورة التالية:
وسائل الإعلام
عند إضافة صورة إلى منتج "يدويًا" من خلال لوحة الإدارة، تتم كتابة المعلومات ذات الصلة في الجداول التالية:
catalog_product_entity_media_gallery: تسجيل الوسائط (الصور وملفات الفيديو)؛
catalog_product_entity_media_gallery_value: ربط الوسائط بالمنتجات وواجهات العرض (التعريب)؛
catalog_product_entity_media_gallery_value_to_entity: ربط الوسائط بالمنتجات فقط (من المفترض أن يكون محتوى الوسائط الافتراضي للمنتج)؛
catalog_product_entity_varchar: يتم حفظ الأدوار التي تستخدم فيها الصورة هنا؛
ويتم حفظ الصور نفسها في الدليل ./pub/media/catalog/product/x/y/حيث x и y - الحرف الأول والثاني من اسم الملف مع الصورة. على سبيل المثال الملف image.png يجب حفظها باسم ./pub/media/catalog/product/i/m/image.pngلتتمكن المنصة من استخدامها كصورة عند وصف المنتجات من الكتالوج.
catalog_product_entity_media_gallery
التسجيل مستضاف في ./pub/media/catalog/product/ ملف الوسائط (لم يتم تناول عملية وضع الملف نفسها في هذه المقالة):
نقوم بربط ملف الوسائط المسجل بالمنتج المقابل دون ربطه بأي عرض. ليس من الواضح أين يتم استخدام هذه البيانات بالضبط ولماذا يستحيل الوصول إلى بيانات الجدول السابق، ولكن هذا الجدول موجود ويتم كتابة البيانات عليه عند إضافة صورة إلى المنتج. لذلك مثل هذا.
الفئة ذات المعرف = 1 هي جذر دليل Magento بأكمله وهي غير متوفرة سواء في المشرف أو في المقدمة. الفئة بالمعرف=2 (افتراضي الفئة) هي الفئة الجذرية للمتجر الرئيسي للموقع الرئيسي (متجر الموقع الرئيسي) تم إنشاؤه عند نشر التطبيق (انظر المشرف / المتاجر / جميع المتاجر). علاوة على ذلك، لا يمكن أيضًا الوصول إلى الفئة الجذرية للمتجر نفسه في المقدمة، فقط فئاته الفرعية.
نظرًا لأن موضوع هذه المقالة لا يزال يستورد بيانات المنتج، فلن أستخدم الإدخال المباشر إلى قاعدة البيانات عند إنشاء الفئات، ولكن سأستخدم الفئات التي توفرها Magento نفسها (النماذج والمستودعات). يتم استخدام الإدخال المباشر في قاعدة البيانات فقط لربط المنتج المستورد بالفئة (تتم مطابقة الفئة باسمها، ويتم استرجاع معرف الفئة عند المطابقة):
يتم استيراد نفس مجموعة المنتجات (10 قطع) كما في المقالة السابقة بسرعة أكبر على الأقل (ثانية واحدة مقابل 1). للحصول على تقييم أكثر دقة للسرعة، تحتاج إلى عدد أكبر من المنتجات - عدة مئات، ويفضل الآلاف. ومع ذلك، حتى مع حجم الإدخال الصغير هذا، يمكن استنتاج أن استخدام مجموعة الأدوات التي توفرها Magento (النماذج والمستودعات) أمر مهم (أؤكد - كثيرا!) تسريع تطوير الوظيفة المطلوبة، ولكن في نفس الوقت بشكل ملحوظ (أؤكد - كثيرا!) تقليل سرعة دخول البيانات إلى قاعدة البيانات.
ونتيجة لذلك، أصبح الماء رطبًا، وهذا ليس وحيًا. ومع ذلك، لدي الآن بعض التعليمات البرمجية التي يمكنني اللعب بها وربما استخلاص استنتاجات أكثر إثارة للاهتمام.