Magento 2: jimporta prodotti direttament fid-database

В artikolu preċedenti Iddeskrivejt il-proċess ta 'importazzjoni ta' prodotti f'Magento 2 bil-mod tas-soltu - permezz ta 'mudelli u repożitorji. Il-metodu tas-soltu għandu veloċità baxxa ħafna tal-ipproċessar tad-data. Il-laptop tiegħi kien qed jipproduċi madwar prodott wieħed kull sekonda. F'din il-kontinwazzjoni, nikkunsidra mod alternattiv biex jimporta prodott - b'dħul dirett fid-database, billi jinjora l-mekkaniżmi standard Magento 2 (mudelli, fabbriki, repożitorji). Is-sekwenza tal-passi għall-importazzjoni ta 'prodotti tista' tiġi adattata għal kwalunkwe lingwa ta 'programmar li tista' taħdem ma 'MySQL.

Ċaħda ta 'responsabbiltà: Magento għandu funzjonalità lesta għal importazzjoni tad-data u, x'aktarx, ikun biżżejjed għalik. Madankollu, jekk għandek bżonn kontroll aktar komplut fuq il-proċess ta 'importazzjoni, mhux limitat għall-preparazzjoni ta' fajl CSV għal dak li għandek, merħba lill-qattus.

Magento 2: jimporta prodotti direttament fid-database

Il-kodiċi li jirriżulta mill-kitba taż-żewġ artikoli jista 'jara fil-modulu Magento "flancer32/mage2_ext_demo_import". Hawn huma xi restrizzjonijiet li segwejt biex nissimplifika l-kodiċi tal-modulu demo:

  • Il-prodotti huma maħluqa biss, mhux aġġornati.
  • Maħżen wieħed
  • L-ismijiet tal-kategoriji biss huma importati, mingħajr l-istruttura tagħhom
  • L-istrutturi tad-dejta jikkonformaw mal-verżjoni 2.3

JSON għall-importazzjoni ta' prodott wieħed:

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

Ħarsa ġenerali lejn l-istadji ewlenin tal-importazzjoni

  • reġistrazzjoni tal-prodott innifsu
  • konnessjoni bejn il-prodott u l-websajt
  • attributi bażiċi tal-prodott (EAV)
  • data tal-inventarju (kwantità tal-prodott fl-istokk)
  • midja (stampi)
  • konnessjoni mal-kategoriji tal-katalgu

Reġistrazzjoni tal-Prodott

L-informazzjoni bażika tal-prodott tista’ tinstab fi 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`)
)

L-informazzjoni minima meħtieġa biex tinħoloq entrata fir-reġistru tal-prodott hija:

  • attribute_set_id
  • sku

addizzjonali:

  • type_id — jekk ma nispeċifikawx, allura jintuża 'sempliċi'

Biex nikteb direttament fid-database, nuża l-adapter DB ta' Magento innifsu:

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

Wara li tirreġistra l-prodott ma catalog_product_entity isir viżibbli fil-pannell tal-amministrazzjoni, fil-grilja tal-prodott (Catalog/Prodotti).

Magento 2: jimporta prodotti direttament fid-database

Relazzjoni bejn il-prodott u l-websajt

L-assoċjazzjoni tal-prodott mas-sit tiddetermina f'liema ħwienet u wirjiet il-prodott se jkun disponibbli fuq quddiem.

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: jimporta prodotti direttament fid-database

Attributi bażiċi tal-prodott

Il-prodott li għadu kif ġie rreġistrat għad m'għandux isem jew deskrizzjoni. Dan kollu jsir permezz Attributi EAV. Hawnhekk hawn lista ta' attributi bażiċi tal-prodott li huma meħtieġa sabiex il-prodott jintwera b'mod korrett fuq in-naħa ta' quddiem:

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

Ma' prodott bħal dan jiżdied attribut separat (id-dettalji tal-kisba tal-identifikatur u t-tip tal-attribut mill-kodiċi tiegħu jitħallew barra):

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

Bl-użu tal-kodiċi tal-attribut, niddeterminaw l-id u t-tip tad-dejta tiegħu (datetime, decimal, int, text, varchar), imbagħad ikteb id-dejta għat-tieqa amministrattiva fit-tabella xierqa (store_id = 0).

Wara li żżid l-attributi ta 'hawn fuq mal-prodott, ikollok din l-istampa fil-pannell tal-amministrazzjoni:

Magento 2: jimporta prodotti direttament fid-database

Data tal-inventarju

Nibdew mill-verżjoni 2.3 f'Magento, hemm żewġ settijiet paralleli ta 'tabelli li jipprovdu ħażna ta' informazzjoni dwar l-inventarju (kwantità tal-prodott):

  • cataloginventory_*: struttura antika;
  • inventory_*: struttura ġdida (MSI - Multi Source Inventory);

Ikollok bżonn iżżid id-dejta tal-inventarju għaż-żewġ strutturi, għaliex l-istruttura l-ġdida għadha mhix kompletament indipendenti mill-qadima (probabbli ħafna li għal default maħżen fl-istruttura l-ġdida tabella hija involuta cataloginventory_stock_status kif inventory_stock_1).

cataloginventory_

Meta niskjeraw Magneto 2.3 inizjalment għandna 2 entrati store_website, li jikkorrispondi għal żewġ siti - amministrattiv u klijent prinċipali:

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

Tabella cataloginventory_stock għandna dħul wieħed biss:

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

Jiġifieri, fl-istruttura l-antika tagħna hemm "maħżen" wieħed biss (stock) u hija marbuta mal-websajt amministrattiva. Żieda ta 'oħrajn ġodda permezz tal-pannell tal-amministrazzjoni sources/stocks fl-MSI (struttura ġdida) ma tirriżultax f’entrati ġodda fi cataloginventory_stock.

Id-dejta tal-inventarju dwar il-prodotti fl-istruttura l-antika hija inizjalment irreġistrata fit-tabelli:

  • cataloginventory_stock_item
  • cataloginventory_stock_status

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,
        /* 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);
}

inventarju_

Inizjalment, l-istruttura l-ġdida għall-ħażna tad-dejta tal-inventarju fiha 1 "sors"(inventory_source):

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

u wieħed"maħżen"(inventory_stock):

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

«Sors» tirrappreżenta l-ħażna fiżika għall-prodotti (ir-rekord fih koordinati fiżiċi u indirizz postali). "Maħżen"hija unjoni loġika ta' diversi "sorsi" (inventory_source_stock_link)

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

fil-livell li fih isseħħ il-konnessjoni mal-kanal tal-bejgħ (inventory_stock_sales_channel)

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

Ġġudikati mill-istruttura tad-dejta, huma preżunti diversi tipi ta 'kanali tal-bejgħ, iżda awtomatikament il-konnessjoni biss "istokk"-"websajt"(il-link għall-websajt issegwi l-kodiċi tal-websajt - base).

Waħda "maħżen"jista' jkun marbut ma' diversi"sorsi"u wieħed"sors"- għal diversi"imħażen"(relazzjoni minn ħafna għal ħafna). L-eċċezzjonijiet huma default "sors"U"maħżen". Mhumiex marbuta mill-ġdid ma' entitajiet oħra (limitazzjoni fil-livell tal-kodiċi - l-iżball "Ma tistax tissejvja link relatata ma' Sors Default jew Stock Default"). Aktar dettalji dwar l-istruttura MSI f'Magento 2 jistgħu jinstabu fl-artiklu "Sistema ta 'ġestjoni tal-maħżen bl-użu ta' CQRS u Event Sourcing. Disinn".

Se nuża l-konfigurazzjoni default u nżid l-informazzjoni kollha tal-inventarju mas-sors default, li hija involuta fil-kanal tal-bejgħ assoċjat mal-websajt bil-kodiċi base (jikkorrispondi għat-tarf ta' quddiem tal-maħżen - ara 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);
}

Wara li żżid id-dejta tal-inventarju mal-prodott fil-pannell tal-amministrazzjoni, ikollok din l-istampa:

Magento 2: jimporta prodotti direttament fid-database

Midja

Meta żżid immaġini "manwalment" ma' prodott permezz tal-pannell tal-amministrazzjoni, l-informazzjoni rilevanti titniżżel fit-tabelli li ġejjin:

  • catalog_product_entity_media_gallery: reġistru tal-midja (immaġini u fajls tal-vidjo);
  • catalog_product_entity_media_gallery_value: rabta tal-midja ma' prodotti u vetrini (lokalizzazzjoni);
  • catalog_product_entity_media_gallery_value_to_entity: rabta tal-midja ma' prodotti biss (preżumibbilment kontenut tal-midja default għall-prodott);
  • catalog_product_entity_varchar: Ir-rwoli li fihom tintuża l-immaġni huma maħżuna hawn;

u l-immaġini nfushom jiġu ssejvjati fid-direttorju ./pub/media/catalog/product/x/y/fejn x и y — l-ewwel u t-tieni ittri tal-isem tal-fajl tal-immaġni. Per eżempju, fajl image.png għandhom jiġu salvati bħala ./pub/media/catalog/product/i/m/image.png, sabiex il-pjattaforma tkun tista' tużaha bħala immaġni meta tiddeskrivi prodotti mill-katalgu.

Reġistru stazzjonat fi ./pub/media/catalog/product/ fajl tal-midja (il-proċess tat-tqegħid tal-fajl innifsu mhuwiex diskuss f'dan l-artikolu):

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

Meta jiġi rreġistrat, fajl tal-midja ġdid jiġi assenjat identifikatur.

Aħna nassoċjaw il-fajl tal-midja reġistrat mal-prodott korrispondenti għall-faċċata default:

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

Aħna nassoċjaw il-fajl tal-midja reġistrat mal-prodott korrispondenti mingħajr ma nkunu marbuta ma 'xi storefront. Mhux ċar fejn tintuża eżattament din id-dejta u għaliex huwa impossibbli li wieħed jaċċessa d-dejta mit-tabella ta’ qabel, iżda din it-tabella teżisti u d-dejta tinkiteb magħha meta tiġi miżjuda stampa mal-prodott. Allura dak hu.

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

Fajl tal-midja jista' jintuża bi rwoli differenti (il-kodiċi tal-attribut korrispondenti huwa indikat fil-parentesi):

  • Bażi(image)
  • Immaġni Żgħira (small_image)
  • Miniatura (thumbnail)
  • Swatch Image (swatch_image)

L-irbit tar-rwoli ma' fajl tal-midja huwa eżattament dak li jiġri fih catalog_product_entity_varchar. Il-kodiċi vinkolanti huwa simili għall-kodiċi fil-"Attributi bażiċi tal-prodott".

Wara li żżid immaġini mal-prodott fil-pannell tal-amministrazzjoni tidher bħal din:

Magento 2: jimporta prodotti direttament fid-database

Категории

Tabelli ewlenin li fihom dejta skont il-kategorija:

  • catalog_category_entity: reġistru tal-kategoriji;
  • catalog_category_product: konnessjoni bejn prodotti u kategoriji;
  • catalog_category_entity_*: Valuri tal-attribut EAV;

Inizjalment, f'applikazzjoni Magento vojta, ir-reġistru tal-kategoriji fih 2 kategoriji (qassar l-ismijiet tal-kolonni: 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|

Il-kategorija b'id=1 hija l-għerq tal-katalgu kollu ta' Magento u mhix disponibbli la fil-pannell tal-amministrazzjoni u lanqas fil-paġna ta' quddiem. Kategorija b'id=2 (Kategorija Default) hija l-kategorija għerq għall-maħżen prinċipali tas-sit prinċipali (Aħżen tal-Websajt Prinċipali) maħluqa meta l-applikazzjoni tiġi skjerata (ara. Admin / Stores / All Stores). Barra minn hekk, il-kategorija ta 'l-għeruq tal-maħżen innifsu lanqas ma hija disponibbli fuq quddiem, biss is-sottokategoriji tagħha.

Peress li s-suġġett ta 'dan l-artikolu għadu qed jimporta data dwar il-prodotti, mhux se nuża dħul dirett fid-database meta noħloq kategoriji, iżda se nuża l-klassijiet ipprovduti minn Magento innifsu (mudelli u repożitorji). Dħul dirett fid-database jintuża biss biex jassoċja l-prodott importat ma' kategorija (il-kategorija hija mqabbla b'isimha, u l-id tal-kategorija tiġi rkuprata waqt it-tqabbil):

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

Wara li żżid link tal-prodott mal-kategoriji "Kategorija 1" u "Kategorija 2", id-dettalji tal-prodott fil-pannell tal-amministrazzjoni jidhru xi ħaġa bħal din:

Magento 2: jimporta prodotti direttament fid-database

Azzjonijiet addizzjonali

Ladarba l-importazzjoni tad-dejta titlesta, trid timla l-passi addizzjonali li ġejjin:

  • indiċjar tad-dejta: sejħa fil-console ./bin/magento indexer:reindex;
  • URLs li jirriġeneraw għal prodotti/kategoriji: tista' tuża l-estensjoni "elgentos/regenerate-catalog-urls«

Prodotti fil-pannell tal-amministrazzjoni wara li twettaq azzjonijiet addizzjonali:

Magento 2: jimporta prodotti direttament fid-database

u fuq quddiem:

Magento 2: jimporta prodotti direttament fid-database

Sommarju

L-istess sett ta 'prodotti (10 biċċiet) bħal fl-artikolu preċedenti huwa importat mill-inqas ordni ta' kobor aktar malajr (sekonda 1 kontra 10). Biex tistma b'mod aktar preċiż il-veloċità, għandek bżonn numru akbar ta 'prodotti - diversi mijiet, jew aħjar eluf. Madankollu, anke b'daqs daqshekk żgħir ta 'data ta' input, nistgħu nikkonkludu li l-użu tal-għodod ipprovduti minn Magento (mudelli u repożitorji) huwa sinifikanti (nenfasizza - ħafna!) tħaffef l-iżvilupp tal-funzjonalità meħtieġa, iżda fl-istess ħin b'mod sinifikanti (nenfasizza - ħafna!) Naqqas il-veloċità li biha d-data tidħol fid-database.

Bħala riżultat, l-ilma rriżulta li kien imxarrab u din mhix rivelazzjoni. Madankollu, issa għandi l-kodiċi biex nilgħab u forsi nasal għal xi konklużjonijiet aktar interessanti.

Sors: www.habr.com