V Olen kirjeldanud toodete importimise protsessi Magento 2 tavapĂ€rasel viisil â mudelite ja reposte pĂ”hiselt. Tavaline viis erineb oluliselt madala andme töötlemise kiirusest. Minu sĂŒlearvutis saadi umbes ĂŒks toode sekundis. Selles jĂ€tkuteoses kĂ€sitlen alternatiivset toodete importimise meetodit â otse andmebaasi kirjutamine, mööda minnes Magento 2 tavapĂ€rastest mehhanismidest (mudelid, tehased, reposte). Tootete importimise samme saab kohandada igasuguste programmeerimiskeelte jaoks, mis suudavad töötada MySQL-iga.
MĂ€rkus: Magento sisaldab olemasolevat funktsionaalsust ja tĂ”enĂ€oliselt piisab teil sellest. Siiski, kui vajate importimisprotsessi ĂŒle rohkem kontrolli, mis ei piirdu ainult CSV-faili ettevalmistamisega tehka â olete teretulnud allapoole.

Kood, mis tekkis pÀrast mÔlema artikli kirjutamist, on saadaval Magento moodulis ««. Siin on mÔned piirangud, mida olen jÀrginud, et lihtsustada demo mooduli koodi:
- Tooted loodetakse ainult, mitte uuendatakse.
- Ăks ladu
- Importitakse ainult kategooriate nimed, ilma nende struktuurita
- Andmestruktuurid vastavad versioonile 2.3
JSON ĂŒksiku toote importimiseks:
{
"sku": "MVA20D-UBV-3",
"name": "VBA47-29 IEK tihend",
"desc": "LigipÀÀsu tagamine seadmetele ...",
"desc_short": "VBA47-29 IEK tihend on mÔeldud ...",
"price": 5.00,
"qty": 25,
"categories": ["Kategooria 1", "Kategooria 2"],
"image_path": "mva20d_ubv_3.png"
}Peamiste importimise sammude ĂŒlevaade
- toote registreerimine
- toote ja veebisaidi seos
- toote pÔhiatribuutid (EAV)
- laoseisud (toote kogus laos)
- meedia (pildid)
- seos katalooge kategooriatega
Toote registreerimine
Toote pÔhiteave asub 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`)
)Minimaalne vajalik teave toote registrisse kandmiseks:
attribute_set_idsku
tÀiendav:
type_idâ kui me ei mĂ€rgi, kasutatakse 'simple'
Otsese andmekirje tegemiseks kasutan Magento DB-adapterit:
function create($sku, $typeId, $attrSetId)
{
/** @var MagentoFrameworkAppResourceConnection $this->resource */
/** @var MagentoFrameworkDBAdapterPdoMysql $conn */
$conn = $this->resource->getConnection();
$table = $this->resource->getTableName('catalog_product_entity');
$bind = [
'sku' => $sku,
'type_id' => $typeId,
'attribute_set_id' => $attrSetId
];
$conn->insert($table, $bind);
$result = $conn->lastInsertId($table);
return $result;
}PÀrast toote registreerimist on see catalog_product_entity nÀhtav administraatoris toote gridis (Kataloog / Tooted).

Toote ja veebisaidi seos
Toote ja saidi seos mÀÀrab, millistes poodides ja mis vitriinidel toode front-end'is saadaval on.
function linkToWebsite($prodId, $websiteId)
{
/** @var MagentoFrameworkAppResourceConnection $this->resource */
/** @var MagentoFrameworkDBAdapterPdoMysql $conn */
$conn = $this->resource->getConnection();
$table = $this->resource->getTableName('catalog_product_website');
$bind = [
'product_id' => $prodId,
'website_id' => $websiteId
];
$conn->insert($table, $bind);
}
Toote pÔhijooned
Hiljuti registreeritud tootel pole veel ei nime ega kirjeldust. KÔik see tehakse lÀbi . Siin on loetelu pÔhjatootest, mis on vajalik toote piisavaks kuvamiseks esiplaanil:
namepricedescriptionlĂŒhikirjeldusstatusmaksu_klass_idurl_vĂ”tinĂ€htavus
Tootele lisatakse eraldi atribuut jĂ€rgmiselt (ĂŒksikasjad atribuudikoodi kaudu ID ja tĂŒĂŒbi saamiseks on jĂ€etud vahele):
public function create($prodId, $attrCode, $attrValue)
{
$attrId = /* saada atribuud ID atribuudikoodi kaudu */
$attrType = /* saada atribuuditĂŒĂŒp [datetime|decimal|int|text|varchar] atribuudikoodi kaudu */
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,
/* pane kÔik atribuudid vaikepoe vaatesse id=0 (admin) */
'store_id' => 0,
'value' => $attrValue
];
$conn->insert($table, $bind);
}
}Atribuudikoodi kaudu mÀÀrame selle ID ja andmetĂŒĂŒbi (datetime, decimal, int, text, varchar), seejĂ€rel kirjutame vastavatesse tabelitesse andmed halduskatalooge (store_id = 0).
PÀrast eeltoodud atribuudide lisamist tootese saadakse administraatorikeskkonnas jÀrgmine pilt:

Laoseisu andmed
Alates versioonist 2.3 eksisteerib Magento-s paralleelselt kaks tabelisarja, mis tagavad inventariteabe (toote kogus) sÀilimise:
cataloginventory_*: vana struktuur;inventory_*: uus struktuur (MSI â Multi Source Inventory);
Inventariandmeid tuleb lisada mÔlemasse struktuuri, kuna uus struktuur ei ole veel tÀielikult vana struktuurist sÔltumatu (tundub, et uue struktuuri puhul on varude kohta kasutusel tabel default cataloginventory_stock_status inventory_stock_1 kui cataloginventory_).
Magneto 2.3 juurutamisel on meil algselt 2 kirjet tabelis
store_website , mis vastab kahele veebisaidile â halduri ja peamise kliendi:website_id|code |name |sort_order|default_group_id|is_default| ----------|-----|------------|----------|----------------|----------| 0|admin|Admin | 0| 0| 0| 1|base |Main Website| 0| 1| 1|
Tabeliscataloginventory_stock on meil ainult ĂŒks kirje: stock_id|website_id|stock_name| --------|----------|----------| 1| 0|Default |
Seega on meie vanas struktuuris ainult ĂŒks âlaoâ (stock) ja see on seotud halduri veebisaidiga. Uutestocks sources/lisamine MSI-sse (uus struktuur) ei too kaasa uute kirjete tekke. MSI (uus struktuur) ei too kaasa uute kirjete tekkimist on meil ainult ĂŒks kirje:.
Toote varude andmed vanas struktuuris on algselt mÀÀratud tabelites:
cataloginventory_stock_iteminventory_stock_1
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,
/* me kasutame 'cataloginventory' struktuuris vaikimisi ĂŒhte varu */
'stock_id' => 1,
'qty' => $qty,
'is_qty_decimal' => $isQtyDecimal,
'is_in_stock' => $isInStock,
/* vaikesaldo on seotud administraatori veebisaidiga (vt `cataloginventory_stock`) */
'website_id' => 0
];
$conn->insert($table, $bind);
}inventory_stock_1
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,
/* me kasutame 'cataloginventory' struktuuris vaikimisi ĂŒhte varu */
'stock_id' => 1,
'qty' => $qty,
'stock_status' => MagentoCatalogInventoryApiDataStockStatusInterface::STATUS_IN_STOCK,
/* vaikesaldo on seotud administraatori veebisaidiga (vt `cataloginventory_stock`) */
'website_id' => 0
];
$conn->insert($table, $bind);
}inventory_
Alguses uus struktuur inventaride andmete hoidmiseks sisaldab 1 "allikas» (inventory_source):
source_code|name |enabled|description |latitude|longitude|country_id|...|
-----------|--------------|-------|--------------|--------|---------|----------|...|
default |Default Source| 1|Default Source|0.000000| 0.000000|US |...|ja ĂŒks «lao» (inventory_stock):
stock_id|name |
--------|-------------|
1|Default Stock|«Allikas» on fĂŒĂŒsiline ladustamisruum toodete jaoks (salvestus sisaldab fĂŒĂŒsilisi koordinaate ja aadressi). «Ladu» on loogiline ĂŒhendus mitme «allika» vahel (inventory_source_stock_link)
link_id|stock_id|source_code|priority|
-------|--------|-----------|--------|
1| 1|default | 1|mille tasandil toimub sidumine mĂŒĂŒgikanaliga (inventory_stock_sales_channel)
type |code|stock_id|
-------|----|--------|
website|base| 1|Andmestruktuuri pĂ”hjal on eeldatavad erinevad mĂŒĂŒgikanali tĂŒĂŒbid, kuid vaikimisi kasutatakse ainult seost «) ja see on seotud halduri veebisaidiga. Uute«-«website» (link veebisaidile lĂ€heb lĂ€bi veebisaidi koodi â base).
Ăks «lao» vĂ”ib olla seotud mitme «allika«, ja ĂŒks «allikas» â mitme «ladude» (suhe «palju-palju»). Erandid on vaikimisi «allikas» ja «lao«. Neid ei saa teistele ĂŒksustele uuesti siduda (kooditasemel piirang â viskab vea «Cannot save link related to Default Source or Default Stock«). Magento 2 MSI struktuuriga saab lĂ€hemalt tutvuda artiklis ««.
Kasutan vaikimisi seadistust ja lisan kogu laoseisu teabe allikale default, mis on seotud mĂŒĂŒgikanaliga, mis on seotud veebisaidiga, millel on kood base (vastab poe kliendipoolsele osale â vt. , mis vastab kahele veebisaidile â halduri ja peamise kliendi:):
function createNewItem($sku, $qty)
{
/** @var MagentoFrameworkAppResourceConnection $this->resource */
/** @var MagentoFrameworkDBAdapterPdoMysql $conn */
$conn = $this->resource->getConnection();
$table = $this->resource->getTableName('inventory_source_item');
$bind = [
'source_code' => 'default',
'sku' => $sku,
'quantity' => $qty,
'status' => MagentoInventoryApiApiDataSourceItemInterface::STATUS_IN_STOCK
];
$conn->insert($table, $bind);
}PÀrast inventariteabe lisamist tooteseadetesse adminpaneelis on tulemuseks jÀrgmine pilt:

Meedia
KÀsitsi toote juurde piltide lisamisel adminpaneelis kantakse vastav teave jÀrgmisesse tabelitesse:
catalog_product_entity_media_gallery: meedia registris (pildid ja videotoad);catalog_product_entity_media_gallery_value: meedia sidumine toodete ja vitriinide (lokaliseerimine);catalog_product_entity_media_gallery_value_to_entity: meedia sidumine ainult toodetega (eeldatavasti toote vaikimisi meediakuidas);catalog_product_entity_varchar: siin salvestatakse rollid, kus kuvatakse pilt;
ja pildid ise salvestatakse katalooge ./pub/media/catalog/product/x/y/, kus x ja y â pildi faili nime esimesed kaks tĂ€hte. NĂ€iteks peab fail image.png olema salvestatud kui ./pub/media/catalog/product/i/m/image.png, et platvorm saaks seda kasutada pildina, kui kirjeldada katalooge tooteid.
catalog_product_entity_media_gallery
Registreerime paigutatud ./pub/media/catalog/product/ meediafail (faili paigutamise protsessi antud artiklis ei kÀsitleta):
function createMediaGallery($imgPathPrefixed)
{
$attrId = /* get attribute ID by attribute code 'media_gallery' */
/** @var MagentoFrameworkAppResourceConnection $this->resource */
/** @var MagentoFrameworkDBAdapterPdoMysql $conn */
$conn = $this->resource->getConnection();
$table = $this->resource->getTableName('catalog_product_entity_media_gallery');
$bind = [
'attribute_id' => $attrId,
'value' => $imgPathPrefixed,
/* 'image' or 'video' */
'media_type' => 'image',
'disabled' => false
];
$conn->insert($table, $bind);
$result = $conn->lastInsertId($table);
return $result;
}Uue meediafaili registreerimisel antakse sellele identifikaator.
catalog_product_entity_media_gallery_value
Seome registreeritud meediafaili vastava tootega vaikimisi kaupluses:
function createGalleryValue($mediaId, $prodId)
{
/** @var MagentoFrameworkAppResourceConnection $this->resource */
/** @var MagentoFrameworkDBAdapterPdoMysql $conn */
$conn = $this->resource->getConnection();
$table = $this->resource->getTableName('catalog_product_entity_media_gallery_value');
$bind = [
'value_id' => $mediaId,
/* use admin store view by default */
'store_id' => 0,
'entity_id' => $prodId,
'label' => null,
/* we have one only image */
'position' => 1,
'disabled' => false
];
$conn->insert($table, $bind);
}catalog_product_entity_media_gallery_value_to_entity
Seome registreeritud meediafaili sidumine vastava tootega, ilma et see oleks seotud mÔne kaupluse kuvandiga. Pole selge, kus tÀpselt neid andmeid kasutatakse ja miks ei saa kasutada eelmist tabelit, kuid see tabel eksisteerib ja andmeid kirjutatakse sinna, kui pilt tootele lisatakse. Seega on asi nii.
function createGalleryValueToEntity($mediaId, $prodId)
{
/** @var MagentoFrameworkAppResourceConnection $this->resource */
/** @var MagentoFrameworkDBAdapterPdoMysql $conn */
$conn = $this->resource->getConnection();
$table = $this->resource->getTableName('catalog_product_entity_media_gallery_value_to_entity');
$bind = [
'value_id' => $mediaId,
'entity_id' => $prodId
];
$conn->insert($table, $bind);
}catalog_product_entity_varchar
Meediafaili saab kasutada erinevate rollidega (sulgudes on vastava atribuudi kood):
- PÔhikomponent (
pilt) - VĂ€ike pilt (
small_image) - Kujutis (
thumbnail) - Proovikuju pilt (
swatch_image)
Rollide seondamine meediafailiga toimub siin catalog_product_entity_varchar. Seondumise kood sarnaneb koodiga jaotises «Toote pÔhijooned«.
PÀrast toote juurde pildi lisamist admin paneelis nÀeb see vÀlja jÀrgmiselt:

Kategooriad
Peamised tabelid, kus on andmed kategooriate kohta:
catalog_category_entity: kategooriate register;catalog_category_product: toodete ja kategooriate seos;catalog_category_entity_*: EAV-atribuutide vÀÀrtused;
Alguses, tĂŒhjas Magento rakenduses on kategooriate registris 2 kategooriat (lĂŒhendasin veergude nimesid: crt â created_at, upd â updated_at):
entity_id|attribute_set_id|parent_id|crt|upd|path|position|level|children_count|
---------|----------------|---------|---|---|----|--------|-----|--------------|
1| 3| 0|...|...|1 | 0| 0| 1|
2| 3| 1|...|...|1/2 | 1| 1| 0|Kategooria id=1 on kogu Magento-katalooge juur ja pole admin paneelis ega eespool saadaval. Kategooria id=2 (Vaikimisi kategooria) on peamise poe juurkategooria peamise saidi (Peamine veebisaidi pood), mis luuakse rakenduse juurutamisel (vt. Admin / Kauplused / KÔik kauplused). TÔepoolest, poe juurkategooria ees ei ole samuti saadaval, ainult selle alamkategooriad.
Kuna selle artikli teema on andmete importimine toodete osas, ei kasuta ma kategooriate loomisel otse andmebaasi kirjutamist, vaid kasutan Magento poolt pakutavaid klasse (mudeleid ja hoidlaid). Otsene andmebaasi kirjutamine toimub ainult imporditud toote sidumiseks kategooriaga (kategooria sidumine toimub selle nime jÀrgi, sidumisel saadakse kategooria ID):
function create($prodId, $catId)
{
/** @var MagentoFrameworkAppResourceConnection $this->resource */
/** @var MagentoFrameworkDBAdapterPdoMysql $conn */
$conn = $this->resource->getConnection();
$table = $this->resource->getTableName('catalog_category_product');
$bind = [
'category_id' => $catId,
'product_id' => $prodId,
];
$conn->insert($table, $bind);
}PĂ€rast toote sidumist kategooriatega âKategooria 1â ja âKategooria 2â nĂ€evad toote detailid administraatori paneelis vĂ€lja umbes nii:

Lisategevused
Andmete importimise lÔpetamisel tuleb teha jÀrgmised lisategevused:
- andmete indeksimine: kutse konsoolis
./bin/magento indexer:reindex; - toodete/kategooriate URL-ide regeneratsioon: saab kasutada laiendust â«
Tooted administraatori paneelis pÀrast lisategevuste tegemist:

ja esimeses:

KokkuvÔte
Sama toodete komplekt (10 tĂŒkki), mis oli eelmises artiklis, imporditakse vĂ€hemalt kordades kiiremini (1 sekund vĂ”rreldes 10). TĂ€psema kiirusanalĂŒĂŒsi jaoks on vajalik suurem tootekogus â paar sada, veel parem kui tuhat. Sellegipoolest, isegi sellise vĂ€ikese sisendi korral saab jĂ€reldada, et Magento poolt pakutud tööriistade (mudelid ja repod) kasutamine kiirendab oluliselt (rĂ”hutan â oluliselt!) nĂ”utava funktsionaalsuse arendust, kuid samas vĂ€hendab mĂ€rgatavalt (rĂ”hutan â oluliselt!) andmete jĂ”udmise kiirus andmebaasi.
KokkuvĂ”ttes, vesi on niiske, ja see pole mingi avastus. Sellegipoolest on mul nĂŒĂŒd kood, millega edasi mĂ€ngida ja vĂ”ib-olla teha huvitavamaid jĂ€reldusi.
Allikas: habr.com
