Magento 2: voer produkte direk in die databasis in
В vorige artikel Ek het die proses om produkte in Magento 2 in te voer op die gewone manier beskryf – deur modelle en bewaarplekke. Die gewone metode het 'n baie lae dataverwerkingspoed. My skootrekenaar het ongeveer een produk per sekonde geproduseer. In hierdie voortsetting oorweeg ek 'n alternatiewe manier om 'n produk in te voer - deur direkte toegang tot die databasis, om die standaard Magento 2-meganismes (modelle, fabrieke, bewaarplekke) te omseil. Die volgorde van stappe om produkte in te voer kan aangepas word by enige programmeertaal wat met MySQL kan werk.
Vrywaring: Magento het klaargemaakte funksionaliteit vir data invoer en, heel waarskynlik, sal dit genoeg wees vir jou. As jy egter meer volledige beheer oor die invoerproses benodig, nie beperk tot die voorbereiding van 'n CSV-lêer vir wat jy het nie, welkom om te kat.
Die kode wat voortspruit uit die skryf van beide artikels kan in die Magento-module bekyk word "flancer32/mage2_ext_demo_import". Hier is 'n paar beperkings wat ek gevolg het om die demo-module-kode te vereenvoudig:
Produkte word slegs geskep, nie opgedateer nie.
Een pakhuis
Slegs kategoriename word ingevoer, sonder hul struktuur
Datastrukture voldoen aan weergawe 2.3
JSON vir die invoer van 'n enkele 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"
}
Oorsig van die hoofstadia van invoer
registrasie van die produk self
verband tussen produk en webwerf
basiese produk eienskappe (EAV)
voorraaddata (hoeveelheid produk in voorraad)
media (prente)
verband met kataloguskategorieë
Produk Registrasie
Basiese produkinligting kan gevind word in 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`)
)
Die minimum inligting wat benodig word om 'n inskrywing in die produkregister te skep, is:
attribute_set_id
sku
bykomende:
type_id - as ons dit nie spesifiseer nie, sal 'eenvoudig' gebruik word
Om direk na die databasis te skryf, gebruik ek die DB-adapter van Magento self:
Die nuut geregistreerde produk het nog nie 'n naam of beskrywing nie. Dit alles word deur gedoen EAV eienskappe. Hier is 'n lys van basiese produkeienskappe wat nodig is om die produk korrek op die voorkant te vertoon:
name
price
description
short_description
status
tax_class_id
url_key
visibility
'n Aparte eienskap word by 'n produk soos hierdie gevoeg (die besonderhede van die verkryging van die identifiseerder en tipe kenmerk uit sy kode word weggelaat):
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);
}
}
Deur die kenmerkkode te gebruik, bepaal ons sy id en datatipe (datetime, decimal, int, text, varchar), skryf dan die data vir die administratiewe venster in die toepaslike tabel (store_id = 0).
Nadat u die bogenoemde eienskappe by die produk gevoeg het, kry u hierdie prentjie in die administrasiepaneel:
Voorraaddata
Vanaf weergawe 2.3 in Magento is daar twee parallelle stelle tabelle wat die berging van voorraadinligting (produkhoeveelheid) verskaf:
cataloginventory_*: ou struktuur;
inventory_*: nuwe struktuur (MSI - Multi Source Inventaris);
Jy moet voorraaddata by beide strukture voeg, want die nuwe struktuur is nog nie heeltemal onafhanklik van die ou een nie (dit is baie waarskynlik dat vir default pakhuis in die nuwe struktuur 'n tafel is betrokke cataloginventory_stock_status as inventory_stock_1).
katalogusvoorraad_
Wanneer Magneto 2.3 ontplooi word, het ons aanvanklik 2 inskrywings in store_website, wat ooreenstem met twee webwerwe - administratiewe en hoofkliënt:
Dit wil sê, in ons ou struktuur is daar net een "pakhuis" (stock) en dit is gekoppel aan die administratiewe webwerf. Voeg nuwes by deur die administrasiepaneel sources/stocks in MSI (nuwe struktuur) lei nie tot nuwe inskrywings in nie cataloginventory_stock.
Voorraaddata oor produkte in die ou struktuur word aanvanklik in tabelle aangeteken:
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);
}
voorraad_
Aanvanklik bevat die nuwe struktuur vir die stoor van voorraaddata 1 "bron"(inventory_source):
«Bron» verteenwoordig die fisiese berging vir produkte (die rekord bevat fisiese koördinate en posadres). "Pakhuis"is 'n logiese vereniging van verskeie "bronne" (inventory_source_stock_link)
op die vlak waarop die verbinding met die verkoopskanaal plaasvind (inventory_stock_sales_channel)
type |code|stock_id|
-------|----|--------|
website|base| 1|
Te oordeel aan die datastruktuur, word verskeie tipes verkoopskanale aanvaar, maar by verstek slegs die verbinding "voorraad"-"webwerf"(die skakel na die webwerf volg die webwerf-kode - base).
Een"winkel"kan aan verskeie gekoppel word"bronne"en een"bron"- aan verskeie"pakhuise"(baie-tot-baie-verhouding). Die uitsonderings is standaard "bron"En"winkel". Hulle word nie weer aan ander entiteite gekoppel nie (beperking op kodevlak - die fout "Kan nie skakel stoor wat verband hou met verstekbron of verstekvoorraad nie"). Meer besonderhede oor die MSI-struktuur in Magento 2 kan gevind word in die artikel "Pakhuisbestuurstelsel wat CQRS en Event Sourcing gebruik. Ontwerp«.
Ek sal die verstekkonfigurasie gebruik en alle voorraadinligting by die bron voeg default, wat betrokke is by die verkoopskanaal wat verband hou met die webwerf met die kode base (kom ooreen met die voorkant van die winkel - sien store_website):
Nadat u voorraaddata by die produk in die administrasiepaneel gevoeg het, kry u hierdie prentjie:
media
Wanneer 'n prent deur die administrasiepaneel "handmatig" by 'n produk gevoeg word, word die relevante inligting in die volgende tabelle neergeskryf:
catalog_product_entity_media_gallery: mediaregister (prente en videolêers);
catalog_product_entity_media_gallery_value: koppeling van media aan produkte en vertoonvensters (lokalisering);
catalog_product_entity_media_gallery_value_to_entity: skakel media slegs aan produkte (vermoedelik verstek media-inhoud vir die produk);
catalog_product_entity_varchar: Die rolle waarin die beeld gebruik word, word hier gestoor;
en die beelde self word in die gids gestoor ./pub/media/catalog/product/x/y/Waar x и y — die eerste en tweede letters van die prentlêernaam. Byvoorbeeld, lêer image.png moet gestoor word as ./pub/media/catalog/product/i/m/image.png, sodat die platform dit as 'n beeld kan gebruik wanneer produkte uit die katalogus beskryf word.
catalog_product_entity_media_galery
Register geplaas in ./pub/media/catalog/product/ medialêer (die proses om die lêer self te plaas word nie in hierdie artikel bespreek nie):
Ons assosieer die geregistreerde medialêer met die ooreenstemmende produk sonder om aan enige winkelfront gekoppel te wees. Dit is nie duidelik waar presies hierdie data gebruik word en hoekom dit onmoontlik is om toegang tot die data van die vorige tabel te kry nie, maar hierdie tabel bestaan en die data word daarheen geskryf wanneer 'n prentjie by die produk gevoeg word. So dit is dit.
'n Medialêer kan met verskillende rolle gebruik word (die ooreenstemmende kenmerkkode word tussen hakies aangedui):
Basis(image)
Klein prent (small_image)
Kleinkiekie (thumbnail)
Swatch-prent (swatch_image)
Om rolle aan 'n medialêer te koppel is presies wat in gebeur catalog_product_entity_varchar. Die bindingskode is soortgelyk aan die kode in die "Basiese produk eienskappe«.
Nadat 'n prent by die produk in die administrasiepaneel gevoeg is, lyk dit soos volg:
Категории
Hooftabelle wat data volgens kategorie bevat:
catalog_category_entity: register van kategorieë;
catalog_category_product: verband tussen produkte en kategorieë;
catalog_category_entity_*: EAV-kenmerkwaardes;
Aanvanklik, in 'n leë Magento-toepassing, bevat die kategorieregister 2 kategorieë (ek het die kolomname verkort: crt - created_at, upd - updated_at):
Die kategorie met id=1 is die wortel van die hele Magento-katalogus en is nie in die administrasiepaneel of op die voorblad beskikbaar nie. Kategorie met id=2 (standaard Kategorie) is die wortelkategorie vir die hoofwerf se hoofwinkel (Hoof webwerfwinkel) geskep wanneer die toepassing ontplooi word (sien. Admin / Winkels / Alle winkels). Boonop is die wortelkategorie van die winkel self ook nie aan die voorkant beskikbaar nie, slegs sy subkategorieë.
Aangesien die onderwerp van hierdie artikel steeds die invoer van data oor produkte is, sal ek nie direkte toegang tot die databasis gebruik wanneer ek kategorieë skep nie, maar sal die klasse gebruik wat deur Magento self verskaf word (modelle en bewaarplekke). Direkte inskrywing in die databasis word slegs gebruik om die ingevoerde produk met 'n kategorie te assosieer (die kategorie word deur sy naam gepas, en die kategorie-ID word tydens passing herwin):
Nadat 'n produkskakel by die kategorieë "Kategorie 1" en "Kategorie 2" gevoeg is, lyk die produkbesonderhede in die administrasiepaneel iets soos volg:
Bykomende aksies
Sodra die data-invoer voltooi is, moet jy die volgende bykomende stappe voltooi:
data-indeksering: roep die konsole in ./bin/magento indexer:reindex;
Produkte in die administrasiepaneel nadat bykomende handelinge uitgevoer is:
en aan die voorkant:
Opsomming
Dieselfde stel produkte (10 stukke) as in die vorige artikel word ten minste 'n orde van grootte vinniger ingevoer (1 sekonde teenoor 10). Om die spoed meer akkuraat te skat, benodig jy 'n groter aantal produkte - 'n paar honderd, of beter nog duisende. Selfs met so 'n klein grootte van insetdata kan ons egter aflei dat die gebruik van die gereedskap wat deur Magento verskaf word (modelle en bewaarplekke) betekenisvol is (ek beklemtoon - baie!) versnel die ontwikkeling van die vereiste funksionaliteit, maar terselfdertyd aansienlik (ek beklemtoon - baie!) verminder die spoed waarteen data in die databasis kom.
Dit het tot gevolg gehad dat die water nat geword het en dit is nie 'n openbaring nie. Nou het ek egter die kode om mee te speel en dalk tot 'n paar meer interessante gevolgtrekkings te kom.