В iepriekšējais raksts Es aprakstīju produktu importēšanas procesu Magento 2 parastajā veidā - izmantojot modeļus un repozitorijus. Parastajai metodei ir ļoti zems datu apstrādes ātrums. Mans klēpjdators ražoja apmēram vienu produktu sekundē. Šajā turpinājumā es apsveru alternatīvu veidu, kā importēt produktu - ar tiešu ievadi datu bāzē, apejot standarta Magento 2 mehānismus (modeļus, rūpnīcas, krātuves). Produktu importēšanas darbību secību var pielāgot jebkurai programmēšanas valodai, kas var darboties ar MySQL.
Atbildības noraidīšana: Magento ir gatava funkcionalitāte datu importēšana un, visticamāk, tev ar to pietiks. Tomēr, ja jums ir nepieciešama pilnīgāka importēšanas procesa kontrole, neaprobežojoties tikai ar CSV faila sagatavošanu tam, kas jums ir, laipni lūdzam cat.
Abu rakstu rakstīšanas rezultātā iegūto kodu var apskatīt Magento modulī "flancer32/mage2_ext_demo_import". Šeit ir daži ierobežojumi, kurus ievēroju, lai vienkāršotu demonstrācijas moduļa kodu:
Produkti tiek tikai izveidoti, nevis atjaunināti.
Viena noliktava
Tiek importēti tikai kategoriju nosaukumi bez to struktūras
Datu struktūras atbilst versijai 2.3
JSON viena produkta importēšanai:
{
"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"
}
Pārskats par galvenajiem importa posmiem
paša produkta reģistrācija
savienojums starp produktu un vietni
pamata produkta atribūti (EAV)
krājumu dati (produkta daudzums noliktavā)
mediji (attēli)
saistība ar kataloga kategorijām
Produktu reģistrācija
Pamatinformāciju par produktu var atrast 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`)
)
Minimālā informācija, kas nepieciešama, lai izveidotu ierakstu produktu reģistrā, ir:
attribute_set_id
sku
papildus:
type_id — ja mēs to nenorādīsim, tiks izmantots “vienkāršs”.
Lai rakstītu tieši datu bāzē, es izmantoju paša Magento DB adapteri:
Jaunreģistrētajai precei vēl nav ne nosaukuma, ne apraksta. Tas viss tiek darīts cauri EAV atribūti. Šeit ir saraksts ar pamata produkta atribūtiem, kas nepieciešami, lai produkts tiktu pareizi attēlots priekšpusē:
name
price
description
short_description
status
tax_class_id
url_key
visibility
Šādam produktam tiek pievienots atsevišķs atribūts (detaļas par identifikatora iegūšanu un atribūta veidu no tā koda ir izlaista):
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);
}
}
Izmantojot atribūta kodu, mēs nosakām tā id un datu tipu (datetime, decimal, int, text, varchar), pēc tam ierakstiet administratīvā loga datus attiecīgajā tabulā (store_id = 0).
Pēc iepriekš minēto atribūtu pievienošanas produktam administrēšanas panelī tiek parādīts šāds attēls:
Inventāra dati
Sākot ar Magento versiju 2.3, ir divas paralēlas tabulu kopas, kas nodrošina krājumu informācijas (produkta daudzuma) glabāšanu:
cataloginventory_*: veca konstrukcija;
inventory_*: jauna struktūra (MSI - Multi Source Inventory);
Abām struktūrām jāpievieno krājumu dati, jo jaunā struktūra vēl nav pilnībā neatkarīga no vecās (ļoti iespējams, ka priekš default noliktava jaunajā struktūrā ir iesaistīts galds cataloginventory_stock_status kā inventory_stock_1).
kataloga inventārs_
Izvietojot Magneto 2.3, mums sākotnēji ir 2 ieraksti store_website, kas atbilst divām vietnēm - administratīvajam un galvenajam klientam:
Tas ir, mūsu vecajā struktūrā ir tikai viena “noliktava” (stock), un tas ir saistīts ar administratīvo vietni. Jaunu pievienošana, izmantojot administrēšanas paneli sources/stocks MSI (jauna struktūra) nerada jaunus ierakstus cataloginventory_stock.
Krājumu dati par precēm vecajā struktūrā sākotnēji tiek ierakstīti tabulās:
cataloginventory_stock_item
cataloginventory_stock_status
kataloga krājuma_noliktavas_prece
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);
}
kataloga krājumu_statuss
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);
}
inventārs_
Sākotnēji jaunajā krājumu datu glabāšanas struktūrā ir 1 "avots"(inventory_source):
«Avots» apzīmē produktu fizisko krātuvi (ierakstā ir fiziskās koordinātes un pasta adrese). "Noliktava"ir loģiska vairāku "avotu" savienība (inventory_source_stock_link)
līmenī, kurā tiek izveidots savienojums ar pārdošanas kanālu (inventory_stock_sales_channel)
type |code|stock_id|
-------|----|--------|
website|base| 1|
Spriežot pēc datu struktūras, tiek pieņemti dažāda veida pārdošanas kanāli, bet pēc noklusējuma tikai savienojums “krājums"-"mājas lapa"(saite uz vietni seko vietnes kodam - base).
viens"noliktava"var saistīt ar vairākiem"avoti"un viens"avots"- vairākiem"noliktavas"(daudzi pret daudziem attiecības). Izņēmumi ir noklusējuma "avots"Un"noliktava". Tie nav atkārtoti saistīti ar citām entītijām (ierobežojums koda līmenī - kļūda "Nevar saglabāt saiti, kas saistīta ar noklusējuma avotu vai noklusējuma krājumu"). Sīkāku informāciju par MSI struktūru Magento 2 var atrast rakstā "Noliktavas vadības sistēma, izmantojot CQRS un Event Sourcing. Dizains".
Es izmantošu noklusējuma konfigurāciju un pievienošu visu inventāra informāciju avotam default, kas ir iesaistīts pārdošanas kanālā, kas saistīts ar vietni ar kodu base (atbilst veikala priekšpusei - sk store_website):
Pēc krājumu datu pievienošanas produktam administratora panelī tiek parādīts šāds attēls:
Mediju
“Manuāli” pievienojot produktam attēlu, izmantojot administratora paneli, attiecīgā informācija tiek ierakstīta šādās tabulās:
catalog_product_entity_media_gallery: mediju reģistrs (attēli un video faili);
catalog_product_entity_media_gallery_value: mediju saistīšana ar produktiem un vitrīnām (lokalizācija);
catalog_product_entity_media_gallery_value_to_entity: multivides saistīšana tikai ar produktiem (iespējams, produkta noklusējuma multivides saturs);
catalog_product_entity_varchar: šeit tiek saglabātas lomas, kurās tiek izmantots attēls;
un paši attēli tiek saglabāti direktorijā ./pub/media/catalog/product/x/y/Kur x и y — attēla faila nosaukuma pirmais un otrais burts. Piemēram, fails image.png jāsaglabā kā ./pub/media/catalog/product/i/m/image.png, lai platforma to varētu izmantot kā attēlu, aprakstot produktus no kataloga.
catalog_product_entity_media_gallery
Reģistrācija ievietota ./pub/media/catalog/product/ multivides fails (paša faila ievietošanas process šajā rakstā nav apspriests):
Mēs saistām reģistrēto multivides failu ar atbilstošo produktu, nesaistoties ar kādu veikalu. Nav skaidrs, kur tieši šie dati tiek izmantoti un kāpēc nav iespējams piekļūt datiem no iepriekšējās tabulas, taču šī tabula pastāv un dati tajā tiek ierakstīti, kad precei tiek pievienota bilde. Tā nu tas arī viss.
Multivides failu var izmantot ar dažādām lomām (iekavās norādīts atbilstošais atribūta kods):
Bāze(image)
Mazs attēls (small_image)
Sīktēls (thumbnail)
Swatch Image (swatch_image)
Lomu saistīšana ar multivides failu ir tieši tas, kas notiek catalog_product_entity_varchar. Saistošais kods ir līdzīgs kodam laukā "Produkta pamatatribūti".
Pēc attēla pievienošanas produktam administrēšanas panelī tas izskatās šādi:
Kategorija
Galvenās tabulas, kas satur datus pēc kategorijas:
catalog_category_entity: kategoriju reģistrs;
catalog_category_product: saikne starp produktiem un kategorijām;
catalog_category_entity_*: EAV atribūtu vērtības;
Sākotnēji tukšā Magento lietojumprogrammā kategoriju reģistrā ir 2 kategorijas (es saīsināju kolonnu nosaukumus: crt Sākot no created_at, upd Sākot no updated_at):
Kategorija ar id=1 ir visa Magento kataloga sakne, un tā nav pieejama ne administrēšanas panelī, ne pirmajā lapā. Kategorija ar id=2 (Noklusējuma kategorija) ir galvenās vietnes galvenā veikala saknes kategorija (Galvenā vietnes veikals), kas izveidots lietojumprogrammas izvietošanas laikā (sk. Administrators / Veikali / Visi veikali). Turklāt paša veikala saknes kategorija arī nav pieejama priekšpusē, tikai tās apakškategorijas.
Tā kā šī raksta tēma joprojām ir datu importēšana par produktiem, tad, veidojot kategorijas, neizmantošu tiešu ievadi datu bāzē, bet izmantošu paša Magento nodrošinātās klases (modeļus un repozitorijus). Tieša ievade datu bāzē tiek izmantota tikai, lai saistītu importēto produktu ar kategoriju (kategorija tiek saskaņota ar tās nosaukumu, un atbilstības laikā tiek izgūts kategorijas ID):
Produkti administratora panelī pēc papildu darbību veikšanas:
un priekšā:
Kopsavilkums
Tas pats produktu komplekts (10 gab.) kā iepriekšējā rakstā tiek importēts vismaz par lielumu ātrāk (1 sekunde pret 10). Lai precīzāk novērtētu ātrumu, nepieciešams lielāks produktu skaits – vairāki simti vai vēl labāk tūkstoši. Tomēr pat ar tik mazu ievades datu apjomu varam secināt, ka Magento nodrošināto rīku (modeļu un repozitoriju) izmantošana ir nozīmīga (uzsveru - daudz!) paātrināt nepieciešamās funkcionalitātes izstrādi, bet tajā pašā laikā būtiski (uzsveru - daudz!) Samaziniet datu nokļūšanas datubāzē ātrumu.
Rezultātā ūdens izrādījās slapjš un tā nav nekāda atklāsme. Tomēr tagad man ir kods, ar ko spēlēt un, iespējams, nonākt pie vēl interesantākiem secinājumiem.