Magento 2: ngimpor produk langsung kana pangkalan data

В artikel saméméhna Kuring ngajelaskeun prosés ngimpor produk kana Magento 2 dina cara biasa - ngalangkungan modél sareng repositori. Métode anu biasa gaduh laju ngolah data anu rendah pisan. Laptop kuring ngahasilkeun kira-kira hiji produk per detik. Dina tuluyan ieu, kuring mertimbangkeun cara alternatif pikeun ngimpor produk - ku asupna langsung kana pangkalan data, ngalangkungan mékanisme Magento 2 standar (model, pabrik, repositori). Runtuyan léngkah pikeun ngimpor produk tiasa diadaptasi kana basa pamrograman naon waé anu tiasa dianggo sareng MySQL.

Bantahan: Magento boga fungsionalitas siap-dijieun pikeun impor data jeung, paling dipikaresep, eta bakal cukup pikeun anjeun. Nanging, upami anjeun peryogi kontrol anu langkung lengkep dina prosés impor, henteu dugi ka nyiapkeun file CSV pikeun naon anu anjeun gaduh, wilujeng sumping ka ucing.

Magento 2: ngimpor produk langsung kana pangkalan data

Kodeu hasil tina nulis duanana artikel bisa ditempo dina modul Magento "flancer32 / mage2_ext_demo_import". Ieu sababaraha larangan anu kuring dituturkeun pikeun nyederhanakeun kode modul demo:

  • Produk ngan dijieun, teu diropéa.
  • Hiji gudang
  • Ngan ngaran kategori anu diimpor, tanpa strukturna
  • Struktur data sasuai jeung versi 2.3

JSON pikeun ngimpor hiji produk:

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

Tinjauan tina tahap utama impor

  • pendaptaran produk sorangan
  • sambungan antara produk jeung ramatloka
  • atribut produk dasar (EAV)
  • data inventaris (jumlah produk dina stock)
  • média (gambar)
  • sambungan jeung kategori katalog

Pendaptaran produk

Inpormasi produk dasar tiasa dipendakan dina 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`)
)

Inpormasi minimum anu diperyogikeun pikeun nyiptakeun éntri dina pendaptaran produk nyaéta:

  • attribute_set_id
  • sku

tambahan:

  • type_id - lamun urang teu nangtukeun eta, lajeng 'basajan' bakal dipaké

Pikeun nyerat langsung kana pangkalan data, kuring nganggo adaptor DB Magento sorangan:

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

Saatos ngadaptar produk kalawan catalog_product_entity janten katingali dina panel admin, dina grid produk (Katalog / Produk).

Magento 2: ngimpor produk langsung kana pangkalan data

Hubungan antara produk sareng situs wéb

Asosiasi produk sareng situs nangtukeun dimana toko sareng nampilkeun produkna bakal sayogi di payun.

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: ngimpor produk langsung kana pangkalan data

Atribut produk dasar

Produk anu nembe kadaptar henteu acan gaduh nami atanapi déskripsi. Sadaya ieu dilakukeun ngaliwatan atribut EAV. Ieu daptar atribut produk dasar anu diperyogikeun supados produkna tiasa ditingalikeun leres di payun:

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

A atribut misah ditambahkeun kana produk kawas ieu (rincian meunangkeun identifier jeung tipe atribut ti kode na disingkahkeun):

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

Ngagunakeun kode atribut, urang nangtukeun id na tipe data (datetime, decimal, int, text, varchar), teras tulis data pikeun jandela administratif kana tabel anu luyu (store_id = 0).

Saatos nambihan atribut di luhur kana produk, anjeun kéngingkeun gambar ieu dina panel admin:

Magento 2: ngimpor produk langsung kana pangkalan data

Data inventaris

Mimitian ti vérsi 2.3 di Magento, aya dua sét tabel paralel anu nyayogikeun panyimpen inpormasi inventaris (kuantitas produk):

  • cataloginventory_*: struktur heubeul;
  • inventory_*: struktur anyar (MSI - Inventory Multi Sumber);

Anjeun kudu nambahkeun data inventory kana duanana struktur, sabab struktur anyar teu acan sagemblengna bebas tina hiji heubeul (eta kamungkinan pisan yén pikeun default gudang di struktur anyar hiji méja aub cataloginventory_stock_status siga inventory_stock_1).

kataloginventory_

Nalika nyebarkeun Magneto 2.3 kami mimitina ngagaduhan 2 éntri store_website, anu pakait sareng dua situs - klien administratif sareng utama:

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

Méja cataloginventory_stock urang ngan boga hiji entri:

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

Hartina, dina struktur heubeul urang ngan aya hiji "gudang" (stock) sarta ieu numbu ka ramatloka administrasi. Nambahkeun nu anyar ngaliwatan panel admin sources/stocks dina MSI (struktur anyar) henteu ngahasilkeun éntri anyar dina cataloginventory_stock.

Data inventaris ngeunaan produk dina struktur heubeul mimitina kacatet dina tabel:

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

inventaris_

Mimitina, struktur anyar pikeun nyimpen data inventaris ngandung 1 "sumber"(inventory_source):

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

sareng hiji"gudang"(inventory_stock):

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

«sumber» ngagambarkeun panyimpenan fisik pikeun produk (catetan ngandung koordinat fisik sareng alamat surat). "Gudang"mangrupakeun gabungan logis tina sababaraha "sumber" (inventory_source_stock_link)

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

dina tingkat dimana sambungan ka saluran penjualan lumangsung (inventory_stock_sales_channel)

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

Ditilik ku struktur data, rupa-rupa jinis saluran penjualan dianggap, tapi sacara standar ngan ukur sambungan "ancoan"-"website"(Tumbu ka situs wéb nuturkeun kodeu halaman wéb - base).

hiji"gudang"tiasa numbu ka sababaraha"sumber"sareng hiji"sumber"- ka sababaraha"gudang"(hubungan many-to-many). Pangecualian nyaéta standar "sumber"Jeung"gudang". Éta henteu dihubungkeun deui ka éntitas sanés (watesan dina tingkat kode - kasalahan "Teu tiasa nyimpen tautan anu aya hubunganana sareng Sumber Default atanapi Saham Default"). Rincian langkung seueur ngeunaan struktur MSI di Magento 2 tiasa dipendakan dina tulisan "Sistem manajemén gudang nganggo CQRS sareng Acara Sourcing. Desain".

Kuring bakal nganggo konfigurasi standar sareng nambihan sadaya inpormasi inventaris kana sumberna default, nu aub dina saluran jualan pakait sareng ramatloka kalawan kode base (cocog sareng tungtung hareup toko - tingali 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);
}

Saatos nambihan data inventaris kana produk dina panel admin, anjeun nampi gambar ieu:

Magento 2: ngimpor produk langsung kana pangkalan data

Média

Nalika "sacara manual" nambihan gambar kana produk ngaliwatan panel admin, inpormasi anu relevan ditulis dina tabel ieu:

  • catalog_product_entity_media_gallery: pendaptaran média (gambar jeung payil video);
  • catalog_product_entity_media_gallery_value: linking média jeung produk na showcases (lokalisasi);
  • catalog_product_entity_media_gallery_value_to_entity: ngaitkeun média ka produk wungkul (sigana eusi média standar pikeun produk);
  • catalog_product_entity_varchar: Peran dimana gambar dianggo disimpen di dieu;

jeung gambar sorangan disimpen dina diréktori ./pub/media/catalog/product/x/y/dimana x и y - hurup kahiji sareng kadua tina nami file gambar. Contona, file image.png kudu disimpen salaku ./pub/media/catalog/product/i/m/image.png, ku kituna platform nu bisa make eta salaku hiji gambar nalika ngajéntrékeun produk tina katalog.

Ngadaptar dipasang dina ./pub/media/catalog/product/ file media (prosés nempatkeun file sorangan henteu dibahas dina artikel ieu):

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

Nalika didaptarkeun, file média anyar ditugaskeun identifier.

Kami ngahubungkeun file média anu kadaptar sareng produk anu cocog pikeun etalase standar:

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

Kami ngahubungkeun file média anu kadaptar sareng produk anu saluyu sareng henteu dihijikeun kana etalase naon waé. Teu jelas dimana persis data ieu dipaké sarta naha teu mungkin pikeun ngakses data tina tabel saméméhna, tapi tabel ieu aya na data ditulis ka dinya lamun gambar ditambahkeun kana produk. Tah kitu.

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

File media tiasa dianggo sareng peran anu béda (kode atribut anu aya ditunjuk dina kurung):

  • dasar (image)
  • Gambar leutik (small_image)
  • gambar leutik (thumbnail)
  • Gambar Swatch (swatch_image)

Ngahubungkeun peran kana file média mangrupikeun naon anu lumangsung catalog_product_entity_varchar. Kode anu ngariung sami sareng kode dina "Atribut produk dasar".

Saatos nambihan gambar kana produk dina panel admin sigana kieu:

Magento 2: ngimpor produk langsung kana pangkalan data

kategori

Tabél utama anu ngandung data dumasar kategori:

  • catalog_category_entity: ngadaptarkeun kategori;
  • catalog_category_product: sambungan antara produk jeung kategori;
  • catalog_category_entity_*: Nilai atribut EAV;

Mimitina, dina aplikasi Magento kosong, pendaptaran kategori ngandung 2 kategori (kuring disingget nami kolom: 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|

Kategori kalawan id=1 mangrupakeun akar sakabéh katalog Magento sarta henteu sadia boh dina panel admin atawa dina kaca hareup. Kategori sareng id=2 (Kategori standar) nyaéta kategori akar pikeun toko utama situs utama (Toko Situs Web Utama) dijieun nalika aplikasi kasebut disebarkeun (tingali. Admin / Toko / Sadaya Toko). Sumawona, kategori akar toko sorangan ogé henteu sayogi di payun, ngan ukur subkategori na.

Kusabab topik artikel ieu masih ngimpor data ngeunaan produk, kuring moal nganggo éntri langsung kana pangkalan data nalika nyiptakeun kategori, tapi bakal nganggo kelas anu disayogikeun ku Magento sorangan (model sareng repositori). Éntri langsung kana pangkalan data ngan ukur dianggo pikeun ngahubungkeun produk impor sareng kategori (kategori cocog sareng namina, sareng id kategori dicandak nalika cocog):

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

Saatos nambihan tautan produk kana kategori "Kategori 1" sareng "Kategori 2", detil produk dina panel admin katingali sapertos kieu:

Magento 2: ngimpor produk langsung kana pangkalan data

Peta tambahan

Saatos impor data parantos réngsé, anjeun kedah ngalengkepan léngkah-léngkah tambahan ieu:

  • data indexing: nelepon dina konsol nu ./bin/magento indexer:reindex;
  • regenerasi URL pikeun produk / kategori: anjeun tiasa nganggo ekstensi "elgentos / regenerate-katalog-url«

Produk dina panel admin saatos ngalakukeun tindakan tambahan:

Magento 2: ngimpor produk langsung kana pangkalan data

jeung di hareup:

Magento 2: ngimpor produk langsung kana pangkalan data

singgetan

Susunan produk anu sami (10 potongan) sapertos dina tulisan sateuacana diimpor sahenteuna urutan gedéna langkung gancang (1 detik versus 10). Pikeun langkung akurat estimasi laju, anjeun peryogi sajumlah ageung produk - sababaraha ratus, atanapi langkung saé rébuan. Sanajan kitu, sanajan ku ukuran leutik data input, urang bisa nyimpulkeun yén pamakéan alat nu disadiakeun ku Magento (model jeung repositories) signifikan (Kuring ngantebkeun - teuing!) nyepetkeun pangwangunan fungsionalitas anu diperyogikeun, tapi dina waktos anu sami sacara signifikan (kuring nekenkeun - teuing!) Ngurangan laju data asup kana pangkalan data.

Hasilna, cai tétéla jadi baseuh jeung ieu lain wahyu. Sanajan kitu, ayeuna kuring boga kode maén kalawan jeung sugan datang ka sababaraha conclusions leuwih narik.

sumber: www.habr.com