Magento 2: mengimport produk terus ke dalam pangkalan data
Π artikel sebelumnya Saya menerangkan proses mengimport produk ke dalam Magento 2 dengan cara biasa - melalui model dan repositori. Kaedah biasa mempunyai kelajuan pemprosesan data yang sangat rendah. Komputer riba saya menghasilkan kira-kira satu produk sesaat. Dalam kesinambungan ini, saya mempertimbangkan cara alternatif untuk mengimport produk - dengan kemasukan terus ke dalam pangkalan data, memintas mekanisme standard Magento 2 (model, kilang, repositori). Urutan langkah untuk mengimport produk boleh disesuaikan dengan mana-mana bahasa pengaturcaraan yang boleh berfungsi dengan MySQL.
Penafian: Magento mempunyai fungsi sedia untuk import data dan, kemungkinan besar, ia akan mencukupi untuk anda. Walau bagaimanapun, jika anda memerlukan kawalan yang lebih lengkap ke atas proses import, tidak terhad kepada menyediakan fail CSV untuk apa yang anda miliki, selamat datang ke cat.
Kod yang terhasil daripada penulisan kedua-dua artikel boleh dilihat dalam modul Magento βflancer32/mage2_ext_demo_import". Berikut ialah beberapa sekatan yang saya ikuti untuk memudahkan kod modul demo:
Produk hanya dibuat, tidak dikemas kini.
Satu gudang
Hanya nama kategori yang diimport, tanpa strukturnya
Produk yang baru didaftarkan belum mempunyai nama atau keterangan. Semua ini dilakukan melalui Atribut EAV. Berikut ialah senarai atribut produk asas yang diperlukan untuk produk dipaparkan dengan betul di bahagian hadapan:
name
price
description
short_description
status
tax_class_id
url_key
visibility
Atribut yang berasingan ditambahkan pada produk seperti ini (butiran mendapatkan pengecam dan jenis atribut daripada kodnya ditinggalkan):
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);
}
}
Menggunakan kod atribut, kami menentukan id dan jenis datanya (datetime, decimal, int, text, varchar), kemudian tulis data untuk tetingkap pentadbiran ke dalam jadual yang sesuai (store_id = 0).
Selepas menambah atribut di atas pada produk, anda mendapat gambar ini dalam panel pentadbir:
Data inventori
Bermula dari versi 2.3 dalam Magento, terdapat dua set jadual selari yang menyediakan penyimpanan maklumat inventori (kuantiti produk):
cataloginventory_*: struktur lama;
inventory_*: struktur baharu (MSI - Inventori Pelbagai Sumber);
Anda perlu menambah data inventori pada kedua-dua struktur, kerana struktur baru belum sepenuhnya bebas daripada yang lama (kemungkinan besar untuk default gudang dalam struktur baru meja terlibat cataloginventory_stock_status sebagai inventory_stock_1).
kataloginventori_
Apabila menggunakan Magneto 2.3 kami pada mulanya mempunyai 2 entri store_website, yang sepadan dengan dua tapak - pelanggan pentadbiran dan utama:
Iaitu, dalam struktur lama kami hanya terdapat satu "gudang" (stock) dan ia dipautkan ke laman web pentadbiran. Menambah yang baharu melalui panel pentadbir sources/stocks dalam MSI (struktur baharu) tidak menghasilkan entri baharu dalam cataloginventory_stock.
Data inventori tentang produk dalam struktur lama pada mulanya direkodkan dalam jadual:
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);
}
inventori_
Pada mulanya, struktur baharu untuk menyimpan data inventori mengandungi 1 "sumber"(inventory_source):
Β«SourceΒ» mewakili storan fizikal untuk produk (rekod mengandungi koordinat fizikal dan alamat surat-menyurat). "Gudang"adalah kesatuan logik beberapa "sumber" (inventory_source_stock_link)
pada tahap di mana sambungan kepada saluran jualan berlaku (inventory_stock_sales_channel)
type |code|stock_id|
-------|----|--------|
website|base| 1|
Berdasarkan struktur data, pelbagai jenis saluran jualan diandaikan, tetapi secara lalai hanya sambungan "stok"-"laman web"(pautan ke tapak web mengikut kod tapak web - base).
satu"gudang"boleh dikaitkan dengan beberapa"sumber"dan satu "sumber"- kepada beberapa"gudangβ(hubungan ramai-ke-banyak). Pengecualian adalah lalai "sumber"Dan"gudang". Mereka tidak dipautkan semula kepada entiti lain (had pada tahap kod - ralat βTidak dapat menyimpan pautan yang berkaitan dengan Sumber Lalai atau Stok Lalai"). Butiran lanjut tentang struktur MSI dalam Magento 2 boleh didapati dalam artikel βSistem pengurusan gudang menggunakan CQRS dan Event Sourcing. Reka bentuk".
Saya akan menggunakan konfigurasi lalai dan menambah semua maklumat inventori kepada sumber default, yang terlibat dalam saluran jualan yang dikaitkan dengan tapak web dengan kod base (sepadan dengan bahagian hadapan kedai - lihat store_website):
Selepas menambah data inventori pada produk dalam panel pentadbir, anda mendapat gambar ini:
Media
Apabila "secara manual" menambahkan imej pada produk melalui panel pentadbir, maklumat yang berkaitan ditulis dalam jadual berikut:
catalog_product_entity_media_gallery: pendaftaran media (imej dan fail video);
catalog_product_entity_media_gallery_value: menghubungkan media kepada produk dan pameran (penyetempatan);
catalog_product_entity_media_gallery_value_to_entity: memautkan media kepada produk sahaja (mungkin kandungan media lalai untuk produk);
catalog_product_entity_varchar: Peranan di mana imej digunakan disimpan di sini;
dan imej itu sendiri disimpan ke direktori ./pub/media/catalog/product/x/y/Jika x ΠΈ y β huruf pertama dan kedua nama fail imej. Sebagai contoh, fail image.png harus disimpan sebagai ./pub/media/catalog/product/i/m/image.png, supaya platform boleh menggunakannya sebagai imej apabila menerangkan produk daripada katalog.
catalog_product_entity_media_gallery
Daftar disiarkan dalam ./pub/media/catalog/product/ fail media (proses meletakkan fail itu sendiri tidak dibincangkan dalam artikel ini):
Kami mengaitkan fail media berdaftar dengan produk yang sepadan tanpa terikat dengan mana-mana etalase. Tidak jelas di mana tepatnya data ini digunakan dan mengapa adalah mustahil untuk mengakses data daripada jadual sebelumnya, tetapi jadual ini wujud dan data ditulis kepadanya apabila gambar ditambahkan pada produk. Jadi itu sahaja.
Fail media boleh digunakan dengan peranan yang berbeza (kod atribut yang sepadan ditunjukkan dalam kurungan):
asas(image)
Imej Kecil (small_image)
Gambar kecil (thumbnail)
Imej Swatch (swatch_image)
Memautkan peranan kepada fail media ialah perkara yang berlaku di dalamnya catalog_product_entity_varchar. Kod pengikatan adalah serupa dengan kod dalam "Atribut produk asas".
Selepas menambah imej pada produk dalam panel pentadbir, ia kelihatan seperti ini:
ΠΠ°ΡΠ΅Π³ΠΎΡΠΈΠΈ
Jadual utama yang mengandungi data mengikut kategori:
catalog_category_entity: daftar kategori;
catalog_category_product: sambungan antara produk dan kategori;
catalog_category_entity_*: nilai atribut EAV;
Pada mulanya, dalam aplikasi Magento kosong, pendaftaran kategori mengandungi 2 kategori (saya memendekkan nama lajur: crt - created_at, upd - updated_at):
Kategori dengan id=1 ialah punca keseluruhan katalog Magento dan tidak tersedia sama ada dalam panel pentadbir atau di halaman depan. Kategori dengan id=2 (Kategori Lalai) ialah kategori akar untuk stor utama tapak utama (Kedai Laman Web Utama) dicipta apabila aplikasi digunakan (lihat. Pentadbir / Kedai / Semua Kedai). Selain itu, kategori akar kedai itu sendiri juga tidak tersedia di bahagian depan, hanya subkategorinya.
Memandangkan topik artikel ini masih mengimport data pada produk, saya tidak akan menggunakan kemasukan terus ke dalam pangkalan data semasa membuat kategori, tetapi akan menggunakan kelas yang disediakan oleh Magento sendiri (model dan repositori). Kemasukan terus ke dalam pangkalan data hanya digunakan untuk mengaitkan produk yang diimport dengan kategori (kategori dipadankan dengan namanya dan id kategori diambil semasa pemadanan):
Produk dalam panel pentadbir selepas melakukan tindakan tambahan:
dan di hadapan:
Ringkasan
Set produk yang sama (10 keping) seperti dalam artikel sebelumnya diimport sekurang-kurangnya urutan magnitud lebih cepat (1 saat berbanding 10). Untuk menganggarkan kelajuan dengan lebih tepat, anda memerlukan bilangan produk yang lebih besar - beberapa ratus, atau lebih baik lagi beribu-ribu. Walau bagaimanapun, walaupun dengan saiz data input yang begitu kecil, kita boleh membuat kesimpulan bahawa penggunaan alat yang disediakan oleh Magento (model dan repositori) adalah penting (saya menekankan - banyak!) mempercepatkan pembangunan fungsi yang diperlukan, tetapi pada masa yang sama dengan ketara (saya menekankan - banyak!) mengurangkan kelajuan data masuk ke dalam pangkalan data.
Akibatnya, air itu ternyata basah dan ini bukanlah satu pendedahan. Walau bagaimanapun, kini saya mempunyai kod untuk bermain dan mungkin membuat beberapa kesimpulan yang lebih menarik.