В Ech hunn de Prozess vum Import vu Produkter beschriwwen an Magento 2. Déi üblech Method - iwwer Modeller a Repositories. Déi üblech Method zeichnet sech duerch eng ganz niddreg Datenveraarbechtungsgeschwindegkeet aus. Op mengem Laptop huet et ongeféier ee Produkt pro Sekonn produzéiert. An dëser Fortsetzung betruechten ech eng alternativ Method fir Produktimport - direkt an d'Datebank schreiwen, ouni d'Standardmechanismen ze ëmgoen. Magento 2 (Modeller, Fabriken, Repositories). D'Sequenz vun de Schrëtt fir d'Importéiere vu Produkter kann un all Programméiersprooch ugepasst ginn, déi MySQL ënnerstëtzt.
Verzichterklärung: V. Magento et gëtt fäerdeg Funktionalitéit fir an, Wahrscheinlechkeet, et wäert genuch fir Iech ginn. Wann Dir awer méi komplett Kontroll iwwer den Importprozess braucht, net limitéiert op d'Virbereedung vun enger CSV-Datei fir wat Dir hutt, wëllkomm op d'Kaz.

De resultéierende Code fir béid Artikelen kann een op [Lëscht vun de Coden] kucken. Magento-modul "". Hei sinn e puer Restriktiounen déi ech gefollegt hunn fir den Demo Modul Code ze vereinfachen:
- Produkter ginn nëmmen erstallt, net aktualiséiert.
- Ee Lagerhaus
- Nëmmen Kategorie Nimm ginn importéiert, ouni hir Struktur
- Datestrukture entspriechen der Versioun 2.3
JSON fir en eenzegt Produkt z'importéieren:
{
"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"
}Iwwersiicht vun den Haapt Etappe vun Import
- Aschreiwung vum Produkt selwer
- Verbindung tëscht Produkt a Websäit
- Basis Produktattributer (EAV)
- Inventardaten (Quantitéit vum Produkt op Lager)
- Medien (Fotoen)
- Verbindung mat Katalog Kategorien
Produit Aschreiwung
Basis Produktinformatioun kann fonnt ginn an 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`)
)D'Mindest Informatioun déi néideg ass fir eng Entrée am Produktregister ze kreéieren ass:
attribute_set_idsku
zousätzlech:
type_id- wa mir et net spezifizéieren, da gëtt 'einfach' benotzt
Fir direkt an d'Datebank ze schreiwen benotzen ech den DB-Adapter selwer. Magento:
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;
}No der Enregistréiere vum Produit mat catalog_product_entity et gëtt siichtbar am Admin Panel, am Produktraster (Katalog / Produkter).

Relatioun tëscht Produit an Websäit
D'Associatioun vum Produkt mam Site bestëmmt a wéi enge Geschäfter an Affichage de Produit op der Front verfügbar ass.
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);
}
Basis Produit Attributer
Dat nei registréiert Produkt huet nach keen Numm oder Beschreiwung. All dëst gëtt duerchgefouert . Hei ass eng Lëscht mat Basis Produktattributer déi gebraucht ginn fir datt de Produkt richteg op der viischter ugewise gëtt:
namepricedescriptionshort_descriptionstatustax_class_idurl_keyvisibility
E separaten Attribut gëtt un e Produkt wéi dëst bäigefüügt (d'Detailer fir den Identifizéierer an den Typ vum Attribut aus sengem Code ze kréien sinn ausgelooss):
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);
}
}Mat dem Attributcode bestëmmen mir seng ID an Datentyp (datetime, decimal, int, text, varchar), da schreift d'Donnéeën fir d'administrativ Fënster an déi entspriechend Tabell (store_id = 0).
Nodeems Dir déi uewe genannten Attributer zum Produkt bäigefüügt hutt, kritt Dir dëst Bild an der Admin Panel:

Inventar Daten
Zënter der Versioun 2.3 Magento Et ginn zwou parallel Sätz vun Tabellen, déi d'Späicherung vun Inventarinformatiounen (Produktquantitéit) ubidden:
cataloginventory_*: al Struktur;inventory_*: nei Struktur (MSI - Multi Source Inventar);
Dir musst Inventardaten op béid Strukturen addéieren, well déi nei Struktur ass nach net komplett onofhängeg vun der aler (et ass ganz wahrscheinlech datt fir default Lager an der neier Struktur ass en Dësch involvéiert cataloginventory_stock_status wéi inventory_stock_1).
Kataloginventar_
Wann Dir Magneto 2.3 ofsetzt, hu mir am Ufank 2 Entréen an store_website, dat entsprécht zwee Siten - administrativ an Haaptcliente:
website_id|code |name |sort_order|default_group_id|is_default|
----------|-----|------------|----------|----------------|----------|
0|admin|Admin | 0| 0| 0|
1|base |Main Website| 0| 1| 1|Dësch cataloginventory_stock mir hunn nëmmen eng Entrée:
stock_id|website_id|stock_name|
--------|----------|----------|
1| 0|Default |Dat ass, an eiser aler Struktur gëtt et nëmmen een "Lagerhaus" (stock) an et ass mat der administrativer Websäit verlinkt. Füügt nei duerch den Admin Panel sources/stocks an MSI (nei Struktur) féiert net zu neien Entréen an cataloginventory_stock.
Inventardaten iwwer Produkter an der aler Struktur ginn ufanks an Tabellen opgeholl:
cataloginventory_stock_itemcataloginventory_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);
}Inventar_
Am Ufank enthält déi nei Struktur fir Inventardaten ze späicheren 1 "Quell"(inventory_source):
source_code|name |enabled|description |latitude|longitude|country_id|...|
-----------|--------------|-------|--------------|--------|---------|----------|...|
default |Default Source| 1|Default Source|0.000000| 0.000000|US |...|an een"Lager"(inventory_stock):
stock_id|name |
--------|-------------|
1|Default Stock|«Source» representéiert déi kierperlech Lagerung fir Produkter (de Rekord enthält kierperlech Koordinaten a Mailadress). "Lager"ass eng logesch Unioun vu verschiddene "Quellen" (inventory_source_stock_link)
link_id|stock_id|source_code|priority|
-------|--------|-----------|--------|
1| 1|default | 1|um Niveau op deem d'Verbindung zum Verkafskanal geschitt (inventory_stock_sales_channel)
type |code|stock_id|
-------|----|--------|
website|base| 1|No der Datestruktur beurteelen, ginn verschidden Aarte vu Verkafskanäl ugeholl, awer par défaut nëmmen d'Verbindung "rembourséiere"-"Websäit"(de Link op d'Websäit follegt de Websäitcode - base).
Eent "Lager"kann op e puer verbonne ginn"zu Quellen"an een"Quell"- zu e puer"Lagerhaiser"(vill-zu-vill Relatioun). D'Ausnahmen sinn Standard "Quell"An"Lager". Si sinn net mat aneren Entitéite verlinkt (Begrenzung um Codeniveau - de Feeler "Kann de Link net am Zesummenhang mat Standardquell oder Default Stock späicheren"). Méi Detailer iwwer d'MSI Struktur an Magento 2 kann am Artikel gelies ginn "".
Ech wäert d'Standardkonfiguratioun benotzen an all Inventarinformatioun un d'Quell addéieren default, deen am Verkafskanal involvéiert ass mat der Websäit mam Code base (entsprécht dem Frontend vum Geschäft - kuckt 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);
}Nodeems Dir Inventardaten zum Produkt an der Admin Panel bäigefüügt hutt, kritt Dir dëst Bild:

Medien
Wann "manuell" e Bild un e Produkt duerch den Admin Panel bäigefüügt gëtt, gëtt déi relevant Informatioun an de folgenden Tabellen opgeschriwwen:
catalog_product_entity_media_gallery: Medienregistrierung (Biller a Videodateien);catalog_product_entity_media_gallery_value: Medien mat Produkter a Vitrine verbannen (Lokaliséierung);catalog_product_entity_media_gallery_value_to_entity: Verlinkt Medien nëmme mat Produkter (viraussiichtlech Standard Medieninhalt fir de Produit);catalog_product_entity_varchar: D'Rollen an deenen d'Bild benotzt gëtt ginn hei gespäichert;
an d'Biller selwer ginn an den Dossier gespäichert ./pub/media/catalog/product/x/y/wou x и y - déi éischt an zweet Buschtawen vum Bilddatei Numm. Zum Beispill, Fichier image.png soll gespäichert ginn als ./pub/media/catalog/product/i/m/image.png, sou datt d'Plattform et als Bild benotze kann wann Dir Produkter aus dem Katalog beschreiwen.
catalog_product_entity_media_gallery
Registréiert gepost an ./pub/media/catalog/product/ Mediendatei (de Prozess fir d'Datei selwer ze placéieren gëtt net an dësem Artikel diskutéiert):
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;
}Wann registréiert ass, gëtt eng nei Mediendatei en Identifizéierer zougewisen.
catalog_product_entity_media_gallery_value
Mir associéieren déi registréiert Mediendatei mam entspriechende Produkt fir de Standard Storefront:
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
Mir associéieren déi registréiert Mediendatei mam entspriechende Produkt ouni un all Storefront gebonnen ze sinn. Et ass net kloer wou genau dës Donnéeën benotzt ginn a firwat et onméiglech ass op d'Donnéeën aus der viregter Tabelle ze kommen, awer dës Tabell existéiert an d'Donnéeën ginn drop geschriwwe wann e Bild zum Produkt bäigefüügt gëtt. Also dat ass et.
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
Eng Mediendatei ka mat verschiddene Rollen benotzt ginn (de entspriechende Attributcode gëtt an Klammeren uginn):
- Base (
image) - Kleng Bild (
small_image) - Thumbnail (
thumbnail) - Swatch Bild (
swatch_image)
Rollen op eng Mediendatei verknëppelen ass genau dat wat geschitt an catalog_product_entity_varchar. De verbindleche Code ass ähnlech wéi de Code am "Basis Produit Attributer".
Nodeems Dir e Bild zum Produkt an der Admin Panel bäigefüügt hutt, gesäit et esou aus:

Kategorien
Haapttabellen mat Daten no Kategorie:
catalog_category_entity: Register vun Kategorien;catalog_category_product: Verbindung tëscht Produkter a Kategorien;catalog_category_entity_*: EAV Attribut Wäerter;
Ufanks, am Leerraum Magento- de Kategorieregister vun der Applikatioun enthält 2 Kategorien (ech hunn d'Kolonnennimm verkierzt: 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|Kategorie mat id=1 ass d'Wuerzel vun allem Magento-katalog an ass weder am Adminpanel nach am Frontend verfügbar. Kategorie mat id=2 (Standard Kategorie) ass d'Rootkategorie fir den Haaptgeschäft vun der Haaptsäit (Haaptsäit Store) erstallt wann d'Applikatioun ofgebaut gëtt (kuckt. Admin / Stores / All Stores). Ausserdeem ass d'Rootkategorie vum Geschäft selwer och net op der viischter, nëmmen seng Ënnerkategorien.
Well d'Thema vun dësem Artikel nach ëmmer d'Importéiere vu Produktdaten ass, wäert ech beim Erstelle vu Kategorien keen direkten Entrée an d'Datebank benotzen, mä d'Klassen, déi vun der Magento (Modeller a Repositories). Direkt Schreiwen an d'Datebank gëtt nëmme benotzt fir en importéiert Produkt mat enger Kategorie ze associéieren (Kategorievergläich gëtt iwwer säin Numm duerchgefouert, an d'Kategorie-ID gëtt beim Vergläich ofgeruff):
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);
}Nodeems Dir e Produktlink an d'Kategorien "Kategorie 1" an "Kategorie 2" bäigefüügt hutt, kucken d'Produktdetailer an der Admin Panel sou eppes aus:

Zousätzlech Aktiounen
Wann den Datenimport fäerdeg ass, musst Dir déi folgend zousätzlech Schrëtt ausfëllen:
- daten Indexéierung: ruffen an der Konsol
./bin/magento indexer:reindex; - URLen fir Produkter / Kategorien regeneréieren: Dir kënnt d'Extensioun "«
Produkter am Admin Panel nodeems Dir zousätzlech Aktiounen ausféiert:

an un der viischter:

Summary
Dee selwechte Set vu Produkter (10 Artikelen) wéi am viregten Artikel gëtt op d'mannst eng Gréisstenuerdnung méi séier importéiert (1 Sekonn am Verglach zu 10). Eng méi genee Schätzung vun der Geschwindegkeet géif eng méi grouss Zuel vu Produkter erfuerderen - Honnerte, oder nach besser, Dausenden. Trotzdem kann een, och mat sou enger klenger Gréisst vun den Inputdaten, schléissen, datt mat den Tools, déi geliwwert ginn, Magento (Modeller a Späicherplazen), bedeitend (ech betounen - vill!) beschleunegt d'Entwécklung vun der erfuerderter Funktionalitéit, awer gläichzäiteg wesentlech (ech betounen - vill!) reduzéieren d'Geschwindegkeet mat där d'Donnéeën an d'Datebank kommen.
Als Resultat huet d'Waasser sech als naass erausgestallt an dëst ass keng Offenbarung. Wéi och ëmmer, elo hunn ech de Code fir mat ze spillen a vläicht zu e puer méi interessant Conclusiounen ze kommen.
Source: will.com
