Магенто 2: увозите производе директно у базу података
В претходни чланак Процес увоза производа у Магенто 2 описао сам на уобичајен начин – кроз моделе и репозиторије. Уобичајени метод има веома малу брзину обраде података. Мој лаптоп је производио око један производ у секунди. У овом наставку разматрам алтернативни начин увоза производа – директним уласком у базу података, заобилазећи стандардне Магенто 2 механизме (модели, фабрике, ризнице). Редослед корака за увоз производа може се прилагодити било ком програмском језику који може да ради са МиСКЛ.
Одрицање од одговорности: Магенто има готову функционалност за увоз података и, највероватније, биће вам довољно. Међутим, ако вам је потребна потпунија контрола над процесом увоза, не ограничавајући се на припрему ЦСВ датотеке за оно што имате, добродошли у цат.
Код који је резултат писања оба чланка може се видети у Магенто модулу "фланцер32/маге2_ект_демо_импорт„. Ево неких ограничења која сам следио да бих поједноставио код демо модула:
Производи се само креирају, не ажурирају.
Једно складиште
Увозе се само називи категорија, без њихове структуре
Структуре података су у складу са верзијом 2.3
ЈСОН за увоз једног производа:
{
"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"
}
Преглед главних фаза увоза
регистрација самог производа
везу између производа и веб странице
основни атрибути производа (ЕАВ)
подаци о залихама (количина производа на залихама)
медији (слике)
повезаност са каталошким категоријама
Регистрацију производа
Основне информације о производу могу се наћи у 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`)
)
Минималне информације потребне за креирање уноса у регистар производа су:
attribute_set_id
sku
додатно:
type_id — ако га не наведемо, користиће се „једноставно“.
Да пишем директно у базу података, користим ДБ адаптер самог Магента:
Новорегистровани производ још нема назив ни опис. Све ово се ради кроз ЕАВ атрибути. Ево листе основних атрибута производа који су потребни да би производ био исправно приказан на предњој страни:
name
price
description
short_description
status
tax_class_id
url_key
visibility
Овакав производ се додаје посебан атрибут (детаљи о добијању идентификатора и типа атрибута из његовог кода су изостављени):
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);
}
}
Користећи код атрибута, одређујемо његов ИД и тип података (datetime, decimal, int, text, varchar), затим упишите податке за административни прозор у одговарајућу табелу (store_id = 0).
Након додавања горњих атрибута производу, добијате ову слику у админ панелу:
Подаци о инвентару
Почевши од верзије 2.3 у Магенто-у, постоје два паралелна скупа табела које обезбеђују складиштење информација о залихама (количина производа):
cataloginventory_*: стара структура;
inventory_*: нова структура (МСИ - Мулти Соурце Инвентори);
Потребно је да додате податке о залихама у обе структуре, јер нова структура још није потпуно независна од старе (врло је вероватно да за default магацин у новој структури укључен је сто cataloginventory_stock_status као inventory_stock_1).
цаталогинвентори_
Када примењујемо Магнето 2.3, у почетку имамо 2 уноса store_website, што одговара двема локацијама – административном и главном клијенту:
То јест, у нашој старој структури постоји само једно „складиште“ (stock) и повезан је са административном веб локацијом. Додавање нових преко административног панела sources/stocks у МСИ (нова структура) не резултира новим уносима у cataloginventory_stock.
Подаци о залихама производа у старој структури иницијално се евидентирају у табелама:
cataloginventory_stock_item
cataloginventory_stock_status
цаталогинвентори_стоцк_итем
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);
}
цаталогинвентори_стоцк_статус
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);
}
инвентар_
У почетку, нова структура за складиштење података о инвентару садржи 1 "извор"(inventory_source):
«Извор» представља физичко складиште за производе (запис садржи физичке координате и поштанску адресу). "Складиште„је логичан спој неколико „извора“ (inventory_source_stock_link)
на нивоу на коме се јавља веза са каналом продаје (inventory_stock_sales_channel)
type |code|stock_id|
-------|----|--------|
website|base| 1|
Судећи по структури података, претпостављају се различити типови канала продаје, али подразумевано само веза „акције"-""(линк ка веб локацији прати код веб локације - base).
Један "магацин"може бити повезан са неколико"до извора"и један "извор"- на неколико"складишта„(однос „много-према-више“). Изузеци су подразумевани "извор"И"магацин„. Они нису поново повезани са другим ентитетима (ограничење на нивоу кода - грешка “Не могу да сачувам везу која се односи на подразумевани извор или подразумевану залиху"). Више детаља о МСИ структури у Магенто 2 можете пронаћи у чланку “Систем управљања складиштем користећи ЦКРС и Евент Соурцинг. Дизајн".
Користићу подразумевану конфигурацију и додати све информације о инвентару извору default, који је укључен у продајни канал повезан са веб-сајтом са кодом base (одговара предњем крају продавнице - види store_website):
Након додавања података о инвентару производу у админ панелу, добијате ову слику:
Медији
Када „ручно“ додајете слику производу преко административног панела, релевантне информације су записане у следећим табелама:
catalog_product_entity_media_gallery: регистар медија (слике и видео датотеке);
catalog_product_entity_media_gallery_value: повезивање медија са производима и излозима (локализација);
catalog_product_entity_media_gallery_value_to_entity: повезивање медија само са производима (вероватно подразумевани медијски садржај за производ);
catalog_product_entity_varchar: Овде се чувају улоге у којима се слика користи;
а саме слике се чувају у директоријуму ./pub/media/catalog/product/x/y/Где x и y — прво и друго слово имена сликовне датотеке. На пример, фајл image.png треба сачувати као ./pub/media/catalog/product/i/m/image.png, тако да платформа може да га користи као слику при описивању производа из каталога.
цаталог_продуцт_ентити_медиа_галлери
Регистрација објављена у ./pub/media/catalog/product/ медијска датотека (у овом чланку се не говори о самом процесу постављања датотеке):
Ми повезујемо регистровану медијску датотеку са одговарајућим производом без везивања за било који излог. Није јасно где се тачно користе ови подаци и зашто је немогуће приступити подацима из претходне табеле, али ова табела постоји и подаци се у њу уписују када се дода слика у производ. Значи то је то.
Медија датотека се може користити са различитим улогама (одговарајући код атрибута је наведен у заградама):
База (image)
Мала слика (small_image)
сличица (thumbnail)
Узорак слике (swatch_image)
Повезивање улога са медијском датотеком је управо оно што се дешава у catalog_product_entity_varchar. Код за везивање је сличан коду у „Основни атрибути производа".
Након додавања слике производу у админ панел, то изгледа овако:
Категории
Главне табеле које садрже податке по категоријама:
catalog_category_entity: регистар категорија;
catalog_category_product: повезаност производа и категорија;
catalog_category_entity_*: ЕАВ вредности атрибута;
У почетку, у празној Магенто апликацији, регистар категорија садржи 2 категорије (скратио сам називе колона: crt - created_at, upd - updated_at):
Категорија са ид=1 је корен целог Магенто каталога и није доступна ни у админ панелу ни на насловној страни. Категорија са ид=2 (Подразумевана категорија) је основна категорија за главну продавницу главног сајта (Главна веб локација продавница) креиран када се апликација примени (погледајте. Администратор / Продавнице / Све продавнице). Штавише, основна категорија саме продавнице такође није доступна на предњој страни, већ само њене поткатегорије.
Пошто је тема овог чланка и даље увоз података о производима, нећу користити директан улазак у базу података приликом креирања категорија, већ ћу користити класе које обезбеђује сам Магенто (модели и репозиторијуми). Директан улазак у базу података се користи само за повезивање увезеног производа са категоријом (категорија се поклапа са њеним именом, а ИД категорије се преузима током подударања):
Производи у админ панелу након обављања додатних радњи:
и на предњој страни:
Резиме
Исти сет производа (10 комада) као у претходном чланку се увози бар за ред величине брже (1 секунда наспрам 10). Да бисте прецизније проценили брзину, потребан вам је већи број производа - неколико стотина, или још боље хиљаде. Међутим, чак и са тако малом величином улазних података, можемо закључити да је употреба алата које пружа Магенто (модели и репозиторијуми) значајна (наглашавам - много!) убрзавају развој потребне функционалности, али у исто време значајно (наглашавам - много!) смањити брзину којом подаци улазе у базу података.
Као резултат тога, вода се показала мокра и то није откриће. Међутим, сада имам код да се поиграм и можда дођем до неких занимљивијих закључака.