Ostatnio otarłam się o temat modyfikacji atrybutów w magento za pomocą skryptu sql. Nie od dziś wiadomo, że im większy silnik tym więcej relacji, a co za czym idzie większe zamieszanie. Co do nazewnictwa tabel magento jest dość intuicyjne, jednak jest ich tyle, że nie trudno o zawrót głowy.
Zacznijmy może od tego czym jest w ogóle model EAV (Encja-Atrybut-Wartość). Jest to model, który upraszcza opisywanie encji z potencjalnie wieloma atrybutami, co do których w dodatku nie potrzebujemy mieć stałego dostępu. Brzmi enigmatycznie, ale poniższy UML, bazujący na strukturze Magento, powinien zaprezentować to przejrzyściej
Powyższy UML jest mocnym skrótem chociażby dlatego, że tabel z wartościami jest więcej. Magento, każdy typ wartości przechowuje w osobnej tabeli.
- catalog_product_entity_datetime
- catalog_product_entity_decimal
- catalog_product_entity_gallery
- catalog_product_entity_group_price
- catalog_product_entity_int
- catalog_product_entity_media_gallery
- catalog_product_entity_media_gallery_value
- catalog_product_entity_text
- catalog_product_entity_tier_price
- catalog_product_entity_varchar
O tym w jakiej tabeli dana wartość się znajdzie decyduje pole backend_type
w tabeli eav_attribute
. W tabeli tej też znajdziemy nie tylko atrybuty produktów, ale również:
- customer
- customer_address
- customer_payment
- order
- order_status
- order_address
- order_item
- order_payment
- catalog_category
- catalog_product
- quote
- quote_address
- quote_address_rate
- quote_address_item
- quote_item
- quote_payment
- order_status_history
- invoice
- invoice_item
- invoice_shipment
- invoice_comment
- shipment
- shipment_item
- shipment_comment
- shipment_track
- creditmemo
- creditmemo_item
- creditmemo_comment
Jak więc znaleźć właściwe attribute_id
, jeśli mamy kilka atrybutów o tej samej nazwie? To proste decyduje o tym pole entity_type_id
, które jest kluczem obcym dla tabeli eav_entity_type
i pola o tej samej nazwie. Nasze entity_type_id
odpowiada wierszowi, dla którego pole entity_type_code
zawiera wartość catalog_product
.
Ok wiemy więc jak znaleźć nasz upragniony atrybut. Jak to połączyć z produktem? W tabeli catalog_product_entity_int
(patrząc na screen, ale w pozostałych jest podobnie) znajduje się pole entity_id
, które jest kluczem obcym dla tabeli catalog_product_entity
i pola o tej samej nazwie. Pole to reprezentuje ID naszego produktu.
Stwórzmy więc proste zapytanie, które pobierze cenę dowolnie wybranego przez nas produktu:
SELECT cped.value FROM eav_entity_type eet JOIN eav_attribute ea ON eet.entity_type_id = ea.entity_type_id AND ea.attribute_code = 'price' AND eet.entity_type_code = 'catalog_product' JOIN catalog_product_entity_decimal cped ON ea.attribute_id = cped.attribute_id WHERE cped.entity_id = 167
W odwiedzi powinniśmy otrzymać wynik (w moim przypadku):