Magento 2: importoni produkte direkt në bazën e të dhënave
В artikulli i mëparshëm Unë e përshkrova procesin e importimit të produkteve në Magento 2 në mënyrën e zakonshme - përmes modeleve dhe depove. Metoda e zakonshme ka një shpejtësi shumë të ulët të përpunimit të të dhënave. Laptopi im po prodhonte rreth një produkt në sekondë. Në këtë vazhdim, unë konsideroj një mënyrë alternative për të importuar një produkt - duke hyrë direkt në bazën e të dhënave, duke anashkaluar mekanizmat standardë Magento 2 (modele, fabrika, depo). Sekuenca e hapave për importimin e produkteve mund të përshtatet me çdo gjuhë programimi që mund të punojë me MySQL.
Mohim përgjegjësie: Magento ka funksionalitet të gatshëm për importimi i të dhënave dhe, ka shumë të ngjarë, do të jetë e mjaftueshme për ju. Sidoqoftë, nëse keni nevojë për kontroll më të plotë mbi procesin e importit, pa u kufizuar në përgatitjen e një skedari CSV për atë që keni, mirë se vini në cat.
Kodi që rezulton nga shkrimi i të dy artikujve mund të shihet në modulin Magento "flancer32/mage2_ext_demo_import". Këtu janë disa kufizime që kam ndjekur për të thjeshtuar kodin e modulit demo:
Produktet krijohen vetëm, nuk përditësohen.
Një magazinë
Vetëm emrat e kategorive importohen, pa strukturën e tyre
Strukturat e të dhënave përputhen me versionin 2.3
JSON për importimin e një produkti të vetëm:
{
"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"
}
Pasqyrë e fazave kryesore të importit
regjistrimin e vetë produktit
lidhje mes produktit dhe faqes së internetit
atributet bazë të produktit (EAV)
të dhënat e inventarit (sasia e produktit në magazinë)
media (foto)
lidhje me kategoritë e katalogut
Regjistrimi i produktit
Informacioni bazë i produktit mund të gjendet në 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`)
)
Informacioni minimal i kërkuar për të krijuar një hyrje në regjistrin e produktit është:
attribute_set_id
sku
shtesë:
type_id — nëse nuk e specifikojmë, atëherë do të përdoret 'i thjeshtë'
Për të shkruar drejtpërdrejt në bazën e të dhënave, unë përdor përshtatësin DB të vetë Magento:
Produkti i sapo regjistruar nuk ka ende një emër ose përshkrim. E gjithë kjo bëhet përmes Atributet EAV. Këtu është një listë e atributeve bazë të produktit që nevojiten në mënyrë që produkti të shfaqet saktë në pjesën e përparme:
name
price
description
short_description
status
tax_class_id
url_key
visibility
Një atribut i veçantë i shtohet një produkti si ky (të dhënat e marrjes së identifikuesit dhe llojit të atributit nga kodi i tij janë hequr):
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);
}
}
Duke përdorur kodin e atributit, ne përcaktojmë ID-në e tij dhe llojin e të dhënave (datetime, decimal, int, text, varchar), më pas shkruani të dhënat për dritaren administrative në tabelën përkatëse (store_id = 0).
Pas shtimit të atributeve të mësipërme në produkt, ju merrni këtë foto në panelin e administratorit:
Të dhënat e inventarit
Duke filluar nga versioni 2.3 në Magento, ekzistojnë dy grupe paralele tabelash që ofrojnë ruajtjen e informacionit të inventarit (sasia e produktit):
cataloginventory_*: strukturë e vjetër;
inventory_*: struktura e re (MSI - Inventari me shumë burime);
Ju duhet të shtoni të dhënat e inventarit në të dy strukturat, sepse struktura e re nuk është ende plotësisht e pavarur nga e vjetra (ka shumë të ngjarë që për default magazina në strukturën e re është përfshirë një tavolinë cataloginventory_stock_status si inventory_stock_1).
kataloginventari_
Kur vendosim Magneto 2.3 ne fillimisht kemi 2 hyrje store_website, e cila korrespondon me dy faqe - klienti administrativ dhe kryesor:
Kjo do të thotë, në strukturën tonë të vjetër ka vetëm një "depo" (stock) dhe është i lidhur me faqen e internetit administrative. Shtimi i të rejave përmes panelit të administratorit sources/stocks në MSI (struktura e re) nuk rezulton në hyrje të reja në cataloginventory_stock.
Të dhënat e inventarit për produktet në strukturën e vjetër fillimisht regjistrohen në tabela:
cataloginventory_stock_item
cataloginventory_stock_status
kataloginventari_stock_artikull
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);
}
statusi i katalogut të stokut
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);
}
inventari_
Fillimisht, struktura e re për ruajtjen e të dhënave të inventarit përmban 1 "burim'(inventory_source):
«Burim» përfaqëson ruajtjen fizike të produkteve (rekord përmban koordinatat fizike dhe adresën postare). "Magazina"është një bashkim logjik i disa "burimeve" (inventory_source_stock_link)
në nivelin në të cilin ndodh lidhja me kanalin e shitjes (inventory_stock_sales_channel)
type |code|stock_id|
-------|----|--------|
website|base| 1|
Duke gjykuar nga struktura e të dhënave, supozohen lloje të ndryshme të kanaleve të shitjes, por si parazgjedhje vetëm lidhja "aksioneve"-""(lidhja në faqen e internetit ndjek kodin e faqes së internetit - base).
nje"depo"mund të lidhet me disa"burime"dhe një"burim" - për disa "magazina"(marrëdhënie shumë-me-shumë). Përjashtimet janë të paracaktuara "burim"Dhe"depo". Ata nuk janë rilidhur me entitete të tjera (kufizimi në nivelin e kodit - gabimi "Nuk mund të ruhet lidhja në lidhje me Burimin e paracaktuar ose Stokun e paracaktuar"). Më shumë detaje rreth strukturës MSI në Magento 2 mund të gjenden në artikullin "Sistemi i menaxhimit të magazinës duke përdorur CQRS dhe Event Sourcing. Dizajn".
Unë do të përdor konfigurimin e paracaktuar dhe do të shtoj të gjithë informacionin e inventarit në burim default, e cila është e përfshirë në kanalin e shitjeve të lidhur me faqen e internetit me kodin base (korrespondon me pjesën e përparme të dyqanit - shih store_website):
Pas shtimit të të dhënave të inventarit te produkti në panelin e administratorit, ju merrni këtë foto:
media
Kur shtoni "me dorë" një imazh në një produkt përmes panelit të administratorit, informacioni përkatës shkruhet në tabelat e mëposhtme:
catalog_product_entity_media_gallery: regjistri i mediave (skedarët e imazheve dhe videove);
catalog_product_entity_media_gallery_value: lidhja e mediave me produktet dhe ekspozitat (lokalizimi);
catalog_product_entity_media_gallery_value_to_entity: lidhja e mediave vetëm me produktet (me sa duket përmbajtje e paracaktuar e medias për produktin);
catalog_product_entity_varchar: Këtu ruhen rolet në të cilat përdoret imazhi;
dhe vetë imazhet ruhen në drejtori ./pub/media/catalog/product/x/y/Ku x и y — shkronjat e para dhe të dyta të emrit të skedarit të imazhit. Për shembull, skedari image.png duhet të ruhen si ./pub/media/catalog/product/i/m/image.png, në mënyrë që platforma ta përdorë atë si imazh kur përshkruan produktet nga katalogu.
catalog_product_entity_media_gallery
Regjistrohu postuar në ./pub/media/catalog/product/ skedari mediatik (procesi i vendosjes së skedarit në vetvete nuk diskutohet në këtë artikull):
Ne e lidhim skedarin e medias së regjistruar me produktin përkatës pa u lidhur me ndonjë vitrinë. Nuk është e qartë se ku përdoren saktësisht këto të dhëna dhe pse është e pamundur të aksesohen të dhënat nga tabela e mëparshme, por kjo tabelë ekziston dhe të dhënat shkruhen në të kur produkti i shtohet një fotografi. Pra, kjo është ajo.
Një skedar media mund të përdoret me role të ndryshme (kodi përkatës i atributit tregohet në kllapa):
bazë(image)
Imazhi i vogël (small_image)
miniaturë (thumbnail)
Swatch Image (swatch_image)
Lidhja e roleve me një skedar media është pikërisht ajo që ndodh në catalog_product_entity_varchar. Kodi detyrues është i ngjashëm me kodin në "Atributet bazë të produktit".
Pas shtimit të një imazhi në produktin në panelin e administratorit, duket kështu:
Kategoritë
Tabelat kryesore që përmbajnë të dhëna sipas kategorive:
catalog_category_entity: regjistri i kategorive;
catalog_category_product: lidhja ndërmjet produkteve dhe kategorive;
catalog_category_entity_*: vlerat e atributeve EAV;
Fillimisht, në një aplikacion bosh Magento, regjistri i kategorive përmban 2 kategori (unë shkurtova emrat e kolonave: crt - created_at, upd - updated_at):
Kategoria me id=1 është rrënja e të gjithë katalogut Magento dhe nuk është e disponueshme as në panelin e administratorit, as në faqen e parë. Kategoria me id=2 (Kategoria e paracaktuar) është kategoria rrënjësore për dyqanin kryesor të faqes kryesore (Dyqani kryesor i faqes në internet) krijuar kur aplikacioni vendoset (shih. Admin / Dyqanet / Të gjitha Dyqanet). Për më tepër, kategoria rrënjësore e vetë dyqanit gjithashtu nuk është e disponueshme në pjesën e përparme, por vetëm nënkategoritë e saj.
Meqenëse tema e këtij artikulli është ende importimi i të dhënave për produktet, unë nuk do të përdor hyrjen e drejtpërdrejtë në bazën e të dhënave gjatë krijimit të kategorive, por do të përdor klasat e ofruara nga vetë Magento (modele dhe depo). Hyrja e drejtpërdrejtë në bazën e të dhënave përdoret vetëm për të lidhur produktin e importuar me një kategori (kategoria përputhet me emrin e saj dhe id i kategorisë merret gjatë përputhjes):
Produktet në panelin e administratorit pas kryerjes së veprimeve shtesë:
dhe në pjesën e përparme:
Përmbledhje
I njëjti grup produktesh (10 copë) si në artikullin e mëparshëm importohet të paktën një rend i madhësisë më shpejt (1 sekondë kundrejt 10). Për të vlerësuar më saktë shpejtësinë, keni nevojë për një numër më të madh produktesh - disa qindra, ose më mirë akoma mijëra. Sidoqoftë, edhe me një madhësi kaq të vogël të të dhënave hyrëse, mund të konkludojmë se përdorimi i mjeteve të ofruara nga Magento (modele dhe depo) është domethënës (theksoj - shumë!) përshpejtoni zhvillimin e funksionalitetit të kërkuar, por në të njëjtën kohë në mënyrë të konsiderueshme (theksoj - shumë!) zvogëloni shpejtësinë me të cilën të dhënat futen në bazën e të dhënave.
Si rezultat, uji doli të ishte i lagësht dhe kjo nuk është një zbulim. Megjithatë, tani kam kodin për të luajtur dhe ndoshta për të arritur në disa përfundime më interesante.