ProHoster > Blog > Uprava > Magento 2: uvozite izdelke neposredno v bazo podatkov
Magento 2: uvozite izdelke neposredno v bazo podatkov
В prejšnji članek Postopek uvoza izdelkov v Magento 2 sem opisal na običajen način – preko modelov in repozitorijev. Običajna metoda ima zelo nizko hitrost obdelave podatkov. Moj prenosnik je proizvajal približno en izdelek na sekundo. V tem nadaljevanju razmišljam o alternativnem načinu uvoza izdelka - z neposrednim vnosom v bazo podatkov, mimo standardnih mehanizmov Magento 2 (modeli, tovarne, repozitoriji). Zaporedje korakov za uvoz izdelkov je mogoče prilagoditi kateremu koli programskemu jeziku, ki lahko deluje z MySQL.
Zavrnitev odgovornosti: Magento ima že pripravljeno funkcionalnost za uvoz podatkov in najverjetneje vam bo dovolj. Če pa potrebujete popolnejši nadzor nad postopkom uvoza, ki ni omejen na pripravo datoteke CSV za to, kar imate, dobrodošli v cat.
Kodo, ki je nastala pri pisanju obeh člankov, si lahko ogledate v modulu Magento "flancer32/mage2_ext_demo_import". Tukaj je nekaj omejitev, ki sem jih upošteval za poenostavitev kode demo modula:
Izdelki se samo ustvarjajo, ne posodabljajo.
Eno skladišče
Uvožena so samo imena kategorij, brez njihove strukture
Podatkovne strukture so skladne z različico 2.3
JSON za uvoz enega izdelka:
{
"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"
}
Pregled glavnih faz uvoza
registracija samega izdelka
povezava med izdelkom in spletno stranjo
osnovne lastnosti izdelka (EAV)
podatki o zalogi (količina izdelka na zalogi)
mediji (slike)
povezava s kataloškimi kategorijami
Registracija izdelka
Osnovne informacije o izdelku najdete v 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`)
)
Minimalne informacije, potrebne za ustvarjanje vnosa v register izdelkov, so:
attribute_set_id
sku
dodatno:
type_id — če tega ne navedemo, bo uporabljen 'preprost'
Za neposredno pisanje v bazo podatkov uporabljam adapter DB samega Magenta:
Na novo registriran izdelek še nima imena ali opisa. Vse to se izvaja skozi EAV atributi. Tukaj je seznam osnovnih atributov izdelka, ki so potrebni, da je izdelek pravilno prikazan na sprednji strani:
name
price
description
short_description
status
tax_class_id
url_key
visibility
Izdelku, kot je ta, je dodan ločen atribut (podrobnosti o pridobivanju identifikatorja in vrste atributa iz njegove kode so izpuščene):
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);
}
}
S kodo atributa določimo njegov ID in tip podatkov (datetime, decimal, int, text, varchar), nato zapišite podatke za skrbniško okno v ustrezno tabelo (store_id = 0).
Ko izdelku dodate zgornje atribute, dobite to sliko na skrbniški plošči:
Podatki o zalogah
Od različice 2.3 dalje v Magentu obstajata dva vzporedna niza tabel, ki zagotavljata shranjevanje informacij o inventarju (količina izdelkov):
cataloginventory_*: stara zgradba;
inventory_*: nova struktura (MSI - Multi Source Inventory);
Obema strukturama morate dodati podatke o inventarju, ker nova struktura še ni povsem neodvisna od stare (zelo verjetno je za default skladišče v novi strukturi je vključena miza cataloginventory_stock_status kot inventory_stock_1).
kataloški inventar_
Pri uvajanju Magneta 2.3 imamo na začetku 2 vnosa store_website, ki ustreza dvema mestoma - administrativni in glavni stranki:
To pomeni, da je v naši stari strukturi samo eno "skladišče" (stock) in je povezan z administrativno spletno stranjo. Dodajanje novih prek skrbniške plošče sources/stocks v MSI (nova struktura) ne povzroči novih vnosov v cataloginventory_stock.
Inventurni podatki o izdelkih v stari strukturi so na začetku zapisani v tabelah:
cataloginventory_stock_item
cataloginventory_stock_status
catalogueinventory_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);
}
kataloginventory_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);
}
inventar_
Na začetku nova struktura za shranjevanje podatkov o inventarju vsebuje 1 "Vir"(inventory_source):
«Vir» predstavlja fizično skladišče za izdelke (zapis vsebuje fizične koordinate in poštni naslov). "Skladišče"je logična zveza več" virov "(inventory_source_stock_link)
na ravni, na kateri pride do povezave s prodajnim kanalom (inventory_stock_sales_channel)
type |code|stock_id|
-------|----|--------|
website|base| 1|
Po strukturi podatkov sodeč se predvidevajo različne vrste prodajnih kanalov, privzeto pa le povezava »zaloge"-"spletna stran"(povezava do spletnega mesta sledi kodi spletnega mesta - base).
ena"skladišče"lahko se poveže z več"viri"in ena"Vir" - na več "skladišča"(razmerje veliko proti mnogo). Izjeme so privzete "Vir"In"skladišče". Niso ponovno povezani z drugimi subjekti (omejitev na ravni kode - napaka “Povezave, povezane s privzetim virom ali privzeto zalogo, ni mogoče shraniti"). Več podrobnosti o strukturi MSI v Magento 2 najdete v članku “Sistem vodenja skladišč z uporabo CQRS in Event Sourcing. Oblikovanje".
Uporabil bom privzeto konfiguracijo in viru dodal vse informacije o inventarju default, ki je vključen v prodajni kanal, povezan s spletno stranjo s kodo base (ustreza sprednjemu delu trgovine - glejte store_website):
Ko izdelku na skrbniški plošči dodate podatke o inventarju, dobite to sliko:
Mediji
Pri “ročnem” dodajanju slike izdelku preko skrbniške plošče so ustrezni podatki zapisani v naslednjih tabelah:
catalog_product_entity_media_gallery: register medijev (slike in video datoteke);
catalog_product_entity_media_gallery_value: povezovanje medijev z izdelki in izložbami (lokalizacija);
catalog_product_entity_media_gallery_value_to_entity: samo povezovanje medijev z izdelki (verjetno privzeta medijska vsebina za izdelek);
catalog_product_entity_varchar: Tukaj so shranjene vloge, v katerih se uporablja slika;
in slike same se shranijo v imenik ./pub/media/catalog/product/x/y/Če x и y — prva in druga črka imena slikovne datoteke. Na primer datoteka image.png je treba shraniti kot ./pub/media/catalog/product/i/m/image.png, tako da jo lahko platforma uporabi kot sliko pri opisovanju izdelkov iz kataloga.
catalog_product_entity_media_gallery
Register objavljen v ./pub/media/catalog/product/ predstavnostna datoteka (sam postopek namestitve datoteke v tem članku ni obravnavan):
Registrirano predstavnostno datoteko povežemo z ustreznim izdelkom, ne da bi bili vezani na katero koli trgovino. Ni jasno, kje točno se ti podatki uporabljajo in zakaj je nemogoče dostopati do podatkov iz prejšnje tabele, vendar ta tabela obstaja in se podatki vanjo zapišejo, ko se izdelku doda slika. Torej to je to.
Medijska datoteka se lahko uporablja z različnimi vlogami (ustrezna koda atributa je navedena v oklepaju):
Osnova (image)
Majhna slika (small_image)
Sličica (thumbnail)
Vzorčna slika (swatch_image)
Povezovanje vlog z medijsko datoteko je točno to, kar se zgodi v catalog_product_entity_varchar. Vezna koda je podobna kodi v "Osnovne lastnosti izdelka".
Po dodajanju slike izdelku na skrbniški plošči je videti takole:
Категории
Glavne tabele s podatki po kategorijah:
catalog_category_entity: register kategorij;
catalog_category_product: povezava med izdelki in kategorijami;
catalog_category_entity_*: vrednosti atributa EAV;
Na začetku v prazni aplikaciji Magento register kategorij vsebuje 2 kategoriji (imena stolpcev sem skrajšal: crt - created_at, upd - updated_at):
Kategorija z id=1 je koren celotnega kataloga Magento in ni na voljo niti v skrbniški plošči niti na prvi strani. Kategorija z id=2 (Privzeta kategorija) je korenska kategorija za glavno trgovino glavnega mesta (Glavna spletna trgovina), ustvarjeno ob uvedbi aplikacije (glejte. Admin / Trgovine / Vse trgovine). Poleg tega korenska kategorija same trgovine prav tako ni na voljo na sprednji strani, le njene podkategorije.
Ker je tema tega članka še vedno uvoz podatkov o izdelkih, pri ustvarjanju kategorij ne bom uporabljal neposrednega vnosa v bazo, ampak bom uporabil razrede, ki jih ponuja sam Magento (modeli in repozitoriji). Neposredni vnos v zbirko podatkov se uporablja samo za povezovanje uvoženega izdelka s kategorijo (kategorija se ujema z imenom, ID kategorije pa se pridobi med ujemanjem):
Izdelki v skrbniški plošči po izvedbi dodatnih dejanj:
in spredaj:
Povzetek
Isti nabor izdelkov (10 kosov) kot v prejšnjem članku se uvozi vsaj za red velikosti hitreje (1 sekunda proti 10). Za natančnejšo oceno hitrosti potrebujete večje število izdelkov - nekaj sto ali še bolje na tisoče. Vendar pa lahko tudi pri tako majhnem obsegu vhodnih podatkov sklepamo, da je uporaba orodij, ki jih ponuja Magento (modeli in repozitoriji), pomembna (poudarjam - veliko!) pospešiti razvoj zahtevane funkcionalnosti, a hkrati bistveno (poudarjam - veliko!) zmanjšajte hitrost, s katero podatki pridejo v bazo podatkov.
Posledično se je voda izkazala za mokro in to ni razodetje. Zdaj pa imam kodo, s katero se lahko igram in morda pridem do zanimivejših zaključkov.