Magento 2: inportatu produktuak zuzenean datu-basera

Π’ aurreko artikulua Magento 2-ra produktuak inportatzeko prozesua ohiko moduan deskribatu nuen: eredu eta biltegien bidez. Ohiko metodoak datuak prozesatzeko abiadura oso baxua du. Nire ordenagailu eramangarriak segundoko produktu bat inguru ekoizten zuen. Jarraipen honetan, produktu bat inportatzeko modu alternatibo bat hartzen dut kontuan, datu-basean zuzenean sartuz, Magento 2 mekanismo estandarrak (ereduak, fabrikak, biltegiak) alde batera utziz. Produktuak inportatzeko urratsen sekuentzia MySQLrekin lan egin dezakeen edozein programazio-lengoaietara egokitu daiteke.

Lege-oharra: Magentok prest egindako funtzionalitateak ditu datuak inportatzea eta, ziurrenik, nahikoa izango zaizu. Dena den, inportazio-prozesuaren kontrol osoa behar baduzu, duzunarentzat CSV fitxategi bat prestatzera mugatu gabe, ongi etorri cat.

Magento 2: inportatu produktuak zuzenean datu-basera

Bi artikuluak idaztean sortutako kodea Magento moduluan ikus daiteke "flancer32/mage2_ext_demo_import". Hona hemen demo moduluaren kodea sinplifikatzeko jarraitu ditudan murrizketa batzuk:

  • Produktuak soilik sortzen dira, ez eguneratzen.
  • Biltegi bat
  • Kategorien izenak bakarrik inportatzen dira, haien egiturarik gabe
  • Datu-egiturek 2.3 bertsioarekin bat datoz

JSON produktu bakarra inportatzeko:

{
  "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"
}

Inportazioaren fase nagusien ikuspegi orokorra

  • produktuaren beraren erregistroa
  • produktuaren eta webgunearen arteko konexioa
  • produktuaren oinarrizko ezaugarriak (EAV)
  • inbentarioaren datuak (stockeko produktuaren kantitatea)
  • komunikabideak (argazkiak)
  • katalogoko kategoriekin lotura

Produktuen Erregistroa

Produktuen oinarrizko informazioa hemen aurki daiteke 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`)
)

Produktu-erregistroan sarrera bat sortzeko behar den gutxieneko informazioa hau da:

  • attribute_set_id
  • sku

osagarriak:

  • type_id β€” ez badugu zehazten, orduan 'sinple' erabiliko da

Datu-basean zuzenean idazteko, Magentoren beraren DB egokitzailea erabiltzen dut:

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;
}

Produktua erregistratu ondoren catalog_product_entity administrazio panelean, produktuen saretan (Katalogoa/Produktuak).

Magento 2: inportatu produktuak zuzenean datu-basera

Produktuaren eta webgunearen arteko harremana

Produktua gunearekin lotzeak zehazten du zein denda eta erakusleihotan egongo den produktua aurrealdean.

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);
}

Magento 2: inportatu produktuak zuzenean datu-basera

Produktuaren oinarrizko ezaugarriak

Erregistratu berri den produktuak ez du oraindik izenik edo deskribapenik. Hau guztia bidez egiten da EAV atributuak. Hona hemen produktua aurrealdean behar bezala bistaratzeko behar diren oinarrizko produktuen ezaugarrien zerrenda:

  • name
  • price
  • description
  • short_description
  • status
  • tax_class_id
  • url_key
  • visibility

Honelako produktu bati beste atributu bat gehitzen zaio (bere kodetik identifikatzailea eta atributu mota lortzeko xehetasunak ez dira falta):

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);
    }
}

Atributu kodea erabiliz, bere id eta datu mota zehazten ditugu (datetime, decimal, int, text, varchar), ondoren idatzi administrazio-leihorako datuak dagokion taulan (store_id = 0).

Produktuari goiko atributuak gehitu ondoren, argazki hau jasoko duzu administrazio panelean:

Magento 2: inportatu produktuak zuzenean datu-basera

Inbentarioaren datuak

Magentoko 2.3 bertsiotik hasita, bi taula multzo paralelo daude inbentarioaren informazioa gordetzeko (produktu-kopurua):

  • cataloginventory_*: egitura zaharra;
  • inventory_*: egitura berria (MSI - Multi Source Inventory);

Bi egituretan inbentario-datuak gehitu behar dituzu, zeren egitura berria ez da oraindik zaharretik guztiz independentea (oso litekeena da default biltegia egitura berrian mahai batek parte hartzen du cataloginventory_stock_status gisa inventory_stock_1).

katalogoaren inbentarioa_

Magneto 2.3 zabaltzean hasieran 2 sarrera ditugu store_website, bi guneri dagokio: administratiboa eta bezero nagusia:

website_id|code |name        |sort_order|default_group_id|is_default|
----------|-----|------------|----------|----------------|----------|
         0|admin|Admin       |         0|               0|         0|
         1|base |Main Website|         0|               1|         1|

Taula cataloginventory_stock sarrera bakarra dugu:

stock_id|website_id|stock_name|
--------|----------|----------|
       1|         0|Default   |

Hau da, gure egitura zaharrean β€œbiltegi” bakarra dago (stock) eta administrazioaren webgunera estekatuta dago. Admin panelaren bidez berriak gehitzea sources/stocks MSIn (egitura berria) ez du sarrera berririk sortzen cataloginventory_stock.

Egitura zaharreko produktuei buruzko inbentario-datuak tauletan erregistratzen dira hasieran:

  • cataloginventory_stock_item
  • cataloginventory_stock_status

katalogo-inventarioa_stock_elementua

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);
}

inbentarioa_

Hasieran, inbentarioaren datuak gordetzeko egitura berriak 1 " dauka.iturri'(inventory_source):

source_code|name          |enabled|description   |latitude|longitude|country_id|...|
-----------|--------------|-------|--------------|--------|---------|----------|...|
default    |Default Source|      1|Default Source|0.000000| 0.000000|US        |...|

eta bat"denda'(inventory_stock):

stock_id|name         |
--------|-------------|
       1|Default Stock|

Β«IturriaΒ» produktuen biltegiratze fisikoa adierazten du (erregistroak koordenatu fisikoak eta posta helbidea ditu). "Π‘ΠΊΠ»Π°Π΄"hainbat "iturri"ren batasun logikoa da (inventory_source_stock_link)

link_id|stock_id|source_code|priority|
-------|--------|-----------|--------|
      1|       1|default    |       1|

salmenta-kanalarekiko konexioa gertatzen den mailan (inventory_stock_sales_channel)

type   |code|stock_id|
-------|----|--------|
website|base|       1|

Datuen egituraren arabera, hainbat salmenta kanal mota suposatzen dira, baina lehenespenez konexioa bakarrik "stock"-" "(Webgunerako estekak webgunearen kodeari jarraitzen dio - base).

Bat "denda"hainbatekin lotu daiteke"iturri"eta bat"iturri"- hainbatei"biltegiak"(askoren arteko harremana). Salbuespenak lehenetsiak dira "iturri"Eta"denda". Ez daude berriro lotzen beste entitateekin (kode mailan muga - errorea "Ezin da gorde iturri lehenetsiarekin edo stock lehenetsiarekin erlazionatutako esteka"). Magento 2-n MSI egiturari buruzko xehetasun gehiago " artikuluan aurki daitezkeBiltegiak kudeatzeko sistema CQRS eta Event Sourcing erabiliz. Diseinua".

Lehenetsitako konfigurazioa erabiliko dut eta inbentarioaren informazio guztia gehituko dut iturrira default, kodearekin webguneari lotutako salmenta kanalean parte hartzen duena base (dendaren aurrealdeari dagokio - ikus store_website):

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);
}

Admin panelean produktuari inbentario-datuak gehitu ondoren, argazki hau jasoko duzu:

Magento 2: inportatu produktuak zuzenean datu-basera

media

Admin panelaren bidez produktu bati irudi bat "eskuz" gehitzean, dagokion informazioa hurrengo tauletan idazten da:

  • catalog_product_entity_media_gallery: multimedia-erregistroa (irudiak eta bideo-fitxategiak);
  • catalog_product_entity_media_gallery_value: komunikabideak produktuekin eta erakusleihoekin lotzea (lokalizazioa);
  • catalog_product_entity_media_gallery_value_to_entity: multimedia produktuekin soilik lotzea (ustez produktuaren multimedia eduki lehenetsia);
  • catalog_product_entity_varchar: Irudia erabiltzen den rolak gordetzen dira hemen;

eta irudiak berak direktorioan gordetzen dira ./pub/media/catalog/product/x/y/Non x ΠΈ y β€” Irudi-fitxategiaren izenaren lehen eta bigarren letrak. Adibidez, fitxategia image.png gisa gorde behar da ./pub/media/catalog/product/i/m/image.png, plataformak irudi gisa erabil dezan katalogoko produktuak deskribatzerakoan.

Erregistratu argitaratuta ./pub/media/catalog/product/ multimedia fitxategia (fitxategia bera jartzeko prozesua ez da artikulu honetan eztabaidatzen):

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;
}

Erregistratzean, multimedia fitxategi berri bati identifikatzaile bat esleitzen zaio.

Erregistratutako multimedia fitxategia erakusleiho lehenetsiari dagokion produktuarekin lotzen dugu:

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);
}

Erregistratutako multimedia-fitxategia dagokion produktuarekin lotzen dugu inongo erakusleihoetara lotu gabe. Ez dago argi non erabiltzen diren zehatz-mehatz datu horiek eta zergatik den ezinezkoa den aurreko taulako datuetara sartzea, baina taula hau existitzen da eta produktuari argazki bat gehitzean datuak bertan idazten dira. Beraz, hori da.

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

Multimedia-fitxategi bat rol ezberdinekin erabil daiteke (dagokion atributu-kodea parentesi artean adierazten da):

  • Oinarria(image)
  • Irudi txikia (small_image)
  • Miniatura (thumbnail)
  • Swatch irudia (swatch_image)

Rolak multimedia-fitxategi bati lotzea da zehazki gertatzen dena catalog_product_entity_varchar. Lotura-kodea ""-ko kodearen antzekoa daProduktuaren oinarrizko ezaugarriak".

Admin panelean produktuari irudi bat gehitu ondoren, itxura hau du:

Magento 2: inportatu produktuak zuzenean datu-basera

ΠšΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠΈ

Kategoriaren arabera datuak dituzten taula nagusiak:

  • catalog_category_entity: kategorien erregistroa;
  • catalog_category_product: produktuen eta kategorien arteko lotura;
  • catalog_category_entity_*: EAV atributuen balioak;

Hasieran, Magento aplikazio huts batean, kategorien erregistroak 2 kategoria ditu (zutabeen izenak laburtu ditut: 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|

Id=1 duen kategoria Magento katalogo osoaren erroa da eta ez dago erabilgarri ez administrazio-panelean ez aurreko orrian. Id=2 duen kategoria (Kategoria lehenetsia) gune nagusiaren denda nagusiaren erro kategoria da (Webgune nagusia denda) aplikazioa zabaltzen denean sortu da (ikus. Administratzailea / Dendak / Dendak guztiak). Gainera, dendaren erro-kategoria bera ere ez dago eskuragarri aurrealdean, bere azpikategoriak bakarrik.

Artikulu honen gaia oraindik produktuen datuak inportatzen ari denez, ez dut datu-basean sarrera zuzena erabiliko kategoriak sortzerakoan, baizik eta Magentok berak emandako klaseak (ereduak eta biltegiak) erabiliko ditu. Datu-basean zuzeneko sarrera inportatutako produktua kategoria batekin lotzeko soilik erabiltzen da (kategoria bere izenarekin bat dator, eta kategoriako IDa lortzen da parekatzean):

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);
}

"1. Kategoria" eta "2. Kategoria" kategorietan produktuaren esteka gehitu ondoren, administrazio-paneleko produktuaren xehetasunak honelakoak dira:

Magento 2: inportatu produktuak zuzenean datu-basera

Ekintza osagarriak

Datuen inportazioa amaitutakoan, urrats gehigarri hauek bete behar dituzu:

  • datuen indexazioa: deitu kontsolan ./bin/magento indexer:reindex;
  • produktu/kategorien URLak birsortzea: luzapena erabil dezakezu "elgentos/regenerate-catalog-urlsΒ«

Produktuak administrazio panelean ekintza gehigarriak egin ondoren:

Magento 2: inportatu produktuak zuzenean datu-basera

eta aurrealdean:

Magento 2: inportatu produktuak zuzenean datu-basera

Laburpena

Aurreko artikuluko produktu-multzo bera (10 pieza) gutxienez magnitude ordena bat azkarrago inportatzen da (segundo 1 versus 10). Abiadura zehatzago kalkulatzeko, produktu-kopuru handiagoa behar duzu, ehunka, edo hobeto esanda, milaka. Hala ere, sarrerako datuen tamaina txikia izanik ere, Magentok eskaintzen dituen tresnen (ereduak eta biltegiak) erabilera esanguratsua dela ondoriozta dezakegu (azpimarratzen dut - askoz!) behar diren funtzionalitateen garapena bizkortu, baina aldi berean nabarmen (azpimarratzen dut - askoz!) murriztu datuak datu-basean sartzeko abiadura.

Ondorioz, ura bustita zegoen eta hau ez da errebelazioa. Hala ere, orain badut kodea jolasteko eta agian ondorio interesgarriagoak ateratzeko.

Iturria: www.habr.com