Magento 2. ներմուծել ապրանքներ անմիջապես տվյալների բազա
В նախորդ հոդվածը Ես նկարագրեցի Magento 2 ապրանքների ներմուծման գործընթացը սովորական ձևով՝ մոդելների և պահեստների միջոցով: Սովորական մեթոդն ունի տվյալների մշակման շատ ցածր արագություն: Իմ նոութբուքը վայրկյանում մոտավորապես մեկ ապրանք էր արտադրում: Այս շարունակության մեջ դիտարկում եմ ապրանքի ներմուծման այլընտրանքային տարբերակ՝ ուղղակի մուտքագրելով տվյալների բազա՝ շրջանցելով ստանդարտ Magento 2 մեխանիզմները (մոդելներ, գործարաններ, պահեստներ)։ Ապրանքների ներմուծման քայլերի հաջորդականությունը կարող է հարմարեցվել ցանկացած ծրագրավորման լեզվին, որը կարող է աշխատել MySQL-ի հետ:
Հրաժարում պատասխանատվությունիցMagento-ն ունի պատրաստի ֆունկցիոնալություն տվյալների ներմուծում և, ամենայն հավանականությամբ, դա ձեզ կբավականացնի։ Այնուամենայնիվ, եթե ձեզ անհրաժեշտ է ավելի ամբողջական վերահսկողություն ներմուծման գործընթացի վրա, չսահմանափակվելով ձեր ունեցածի համար CSV ֆայլ պատրաստելով, բարի գալուստ cat:
Երկու հոդվածները գրելուց ստացված կոդը կարելի է դիտել Magento մոդուլում:flancer32/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-ի DB ադապտեր.
Նոր գրանցված ապրանքը դեռ անուն կամ նկարագրություն չունի։ Այս ամենը կատարվում է միջոցով EAV հատկանիշներ. Ահա հիմնական ապրանքի ատրիբուտների ցանկը, որոնք անհրաժեշտ են, որպեսզի ապրանքը ճիշտ ցուցադրվի առջևում.
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);
}
}
Օգտագործելով հատկանիշի կոդը, մենք որոշում ենք դրա ID-ն և տվյալների տեսակը (datetime, decimal, int, text, varchar), ապա գրեք ադմինիստրատիվ պատուհանի տվյալները համապատասխան աղյուսակում (store_id = 0).
Ապրանքին վերը նշված հատկանիշները ավելացնելուց հետո ադմինիստրատորի վահանակում ստանում եք այս նկարը.
Գույքագրման տվյալներ
Magento-ում 2.3 տարբերակից սկսած՝ կան աղյուսակների երկու զուգահեռ խմբեր, որոնք ապահովում են գույքագրման տեղեկատվության պահպանում (ապրանքի քանակ).
cataloginventory_*հին կառուցվածքը;
inventory_*նոր կառուցվածք (MSI - Multi Source Inventory);
Երկու կառույցներին էլ պետք է ավելացնեք գույքագրման տվյալները, քանի որ նոր կառույցը դեռ լիովին անկախ չէ հինից (շատ հավանական է, որ համար default պահեստ նոր կառույցում ներառված է սեղան cataloginventory_stock_status ինչպես inventory_stock_1).
կատալոգի գույքագրում_
Magneto 2.3-ը տեղակայելիս սկզբում 2 մուտք ունենք store_website, որը համապատասխանում է երկու կայքի՝ վարչական և հիմնական հաճախորդին.
Այսինքն, մեր հին կառույցում կա միայն մեկ «պահեստ» (stock) և այն կապված է վարչական կայքի հետ: Նորերի ավելացում ադմինիստրատորի վահանակի միջոցով sources/stocks MSI-ում (նոր կառուցվածք) չի հանգեցնում նոր մուտքերի cataloginventory_stock.
Հին կառուցվածքի ապրանքների մասին գույքագրման տվյալները սկզբնապես գրանցվում են աղյուսակներում.
cataloginventory_stock_item
cataloginventory_stock_status
cataloginventory_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);
}
cataloginventory_stock_status
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).
Մեկը"պահեստ«կարելի է կապվել մի քանիսի հետ»աղբյուրները«և մեկ»աղբյուր«- մի քանիսին»պահեստներ«(շատ-շատ հարաբերություններ): Բացառությունները լռելյայն են»աղբյուր"Եւ"պահեստ«. Նրանք կրկին կապված չեն այլ սուբյեկտների հետ (սահմանափակում կոդի մակարդակում՝ սխալ «Հնարավոր չէ պահպանել լռելյայն աղբյուրի կամ կանխադրված բաժնետոմսի հետ կապված հղումը»): Magento 2-ում MSI կառուցվածքի մասին ավելի շատ մանրամասներ կարելի է գտնել հոդվածում «Պահեստի կառավարման համակարգ՝ օգտագործելով CQRS և Event Sourcing: Դիզայն»:
Ես կօգտագործեմ լռելյայն կոնֆիգուրացիան և կավելացնեմ ամբողջ գույքագրման տեղեկատվությունը աղբյուրին 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/ մեդիա ֆայլ (ֆայլի տեղադրման գործընթացը ինքնին չի քննարկվում այս հոդվածում).
Մենք գրանցված մեդիա ֆայլը կապում ենք համապատասխան ապրանքի հետ՝ առանց որևէ խանութի ցուցափեղկի կապվելու: Պարզ չէ, թե կոնկրետ որտեղ են օգտագործվում այս տվյալները և ինչու անհնար է մուտք գործել նախորդ աղյուսակի տվյալները, բայց այս աղյուսակը գոյություն ունի, և տվյալները գրվում են դրա վրա, երբ նկարն ավելացվում է արտադրանքին: Ուրեմն վերջ:
Մեդիա ֆայլը կարող է օգտագործվել տարբեր դերերով (փակագծերում նշված է համապատասխան հատկանիշի կոդը).
Հիմք (image)
Փոքր պատկեր (small_image)
Մանրապատկեր (thumbnail)
Swatch Image (swatch_image)
Դերերը մեդիա ֆայլին կապելը հենց այն է, ինչ տեղի է ունենում ներսում catalog_product_entity_varchar. Պարտադիր ծածկագիրը նման է կոդի «Ապրանքի հիմնական հատկանիշները»:
Ադմինիստրատորի վահանակում ապրանքին պատկեր ավելացնելուց հետո այն ունի հետևյալ տեսքը.
Категории
Հիմնական աղյուսակներ, որոնք պարունակում են տվյալներ ըստ կատեգորիաների.
catalog_category_entityկատեգորիաների ռեգիստր;
catalog_category_productկապ ապրանքների և կատեգորիաների միջև.
catalog_category_entity_*EAV հատկանիշի արժեքները;
Սկզբում, դատարկ Magento հավելվածում, կատեգորիաների ռեեստրը պարունակում է 2 կատեգորիա (ես կրճատել եմ սյունակների անունները. crt - created_at, upd - updated_at):
ID=1-ով կատեգորիան ամբողջ Magento կատալոգի արմատն է և հասանելի չէ ոչ ադմինիստրատորի վահանակում, ոչ էլ առաջին էջում: Կատեգորիա id=2-ով (Կանխադրված կատեգորիա) հիմնական կայքի հիմնական խանութի արմատային կատեգորիան է (Հիմնական կայք խանութ) ստեղծվել է, երբ հավելվածը տեղակայվում է (տես. Ադմինիստրատոր / Խանութներ / Բոլոր խանութները) Ավելին, խանութի արմատային կատեգորիան ինքնին նույնպես հասանելի չէ առջևում, միայն դրա ենթակատեգորիաները:
Քանի որ այս հոդվածի թեման դեռևս ապրանքների վերաբերյալ տվյալների ներմուծումն է, ես կատեգորիաներ ստեղծելիս չեմ օգտագործի տվյալների բազայի ուղղակի մուտքը, այլ կօգտագործեմ հենց Magento-ի կողմից տրամադրված դասերը (մոդելներ և պահեստներ): Տվյալների բազայի ուղղակի մուտքն օգտագործվում է միայն ներմուծված ապրանքը կատեգորիայի հետ կապելու համար (կատեգորիան համընկնում է իր անվան հետ, իսկ կատեգորիայի ID-ն վերցվում է համապատասխանության ժամանակ).
Ապրանքների նույն հավաքածուն (10 հատ), ինչպես նախորդ հոդվածում, ներմուծվում է առնվազն մեծության կարգով ավելի արագ (1 վայրկյան ընդդեմ 10-ի): Արագությունը ավելի ճշգրիտ գնահատելու համար ձեզ հարկավոր է ավելի մեծ քանակությամբ ապրանքներ՝ մի քանի հարյուր, կամ ավելի լավ՝ հազարավոր: Այնուամենայնիվ, նույնիսկ մուտքային տվյալների նման փոքր չափի դեպքում մենք կարող ենք եզրակացնել, որ Magento-ի կողմից տրամադրված գործիքների օգտագործումը (մոդելներ և պահոցներ) նշանակալի է (ընդգծում եմ. շատ!) արագացնել անհրաժեշտ ֆունկցիոնալության զարգացումը, բայց միևնույն ժամանակ զգալիորեն (ընդգծում եմ. շատ!) նվազեցնել տվյալների բազան մուտքագրելու արագությունը:
Արդյունքում ջուրը թաց է ստացվել, և սա բացահայտում չէ։ Այնուամենայնիվ, այժմ ես ունեմ այն կոդը, որի հետ պետք է խաղալ և գուցե ավելի հետաքրքիր եզրակացությունների հանգեմ: