3.01

Attribute Sets & Attributes

Master the concepts of attribute sets, attribute groups, and the differences between EAV and extension attributes for extending Magento entities.

Why This Matters: Understanding attribute sets and attributes is crucial for extending Magento entities like products, categories, and customers. This knowledge allows you to add custom data fields and functionality to these entities.

Attribute Sets & Attributes Overview

mindmap root((Attributes)) Attribute Sets eav_attribute_set table Multiple per product entity Single for categories/customers Groups attributes Attribute Groups eav_attribute_group table Form accordions Rendering purposes EAV Attributes Special tables Automatic save/load Scope support Grid/form support Extension Attributes Custom storage Manual save/load Objects/arrays WebAPI support

Attribute Sets Overview

EAV attributes in Magento are grouped into attribute sets. Each instance of an EAV entity is connected to an attribute set.

Important: Each product has an attribute set. This is also true for categories and customers, but in practice they always stay within a single attribute set. So, attribute sets usually only differ for different products.

Attribute Sets Table Structure

eav_attribute_set Table

All attribute sets are stored in the eav_attribute_set table.

mysql> SELECT * FROM eav_attribute_set;
+------------------+----------------+--------------------+------------+
| attribute_set_id | entity_type_id | attribute_set_name | sort_order |
+------------------+----------------+--------------------+------------+
| 1                | 1              | Default            | 2          |
| 2                | 2              | Default            | 2          |
| 3                | 3              | Default            | 1          |
| 4                | 4              | Default            | 1          |
| 5                | 5              | Default            | 1          |
| 6                | 6              | Default            | 1          |
| 7                | 7              | Default            | 1          |
| 8                | 8              | Default            | 1          |
| 9                | 4              | Top                | 0          |
| 10               | 4              | Bottom             | 0          |
| 11               | 4              | Gear               | 0          |
| 12               | 4              | Sprite Stasis Ball | 0          |
+------------------+----------------+--------------------+------------+
Key Observation: Only the product entity (entity_type_id=4) has multiple attribute sets. Other entities have only a single "Default" attribute set.

Table Columns

Column Purpose Description
attribute_set_id Primary Key Unique identifier for the attribute set
entity_type_id Foreign Key Links to eav_entity_type (1=customer, 2=customer_address, 3=category, 4=product, etc.)
attribute_set_name Display Name Name of the attribute set (e.g., "Default", "Top", "Bottom", "Gear")
sort_order Display Order Controls the order in which attribute sets appear in admin

Attribute Groups

In addition to attribute sets, Magento uses attribute groups for grouping attributes. Attribute groups are used on form pages to create accordions (like Product Details, Images, Content, etc.).

Important: Unlike attribute sets, groups do not have any important function other than rendering attributes on an edit page.

eav_attribute_group Table

Groups are stored in the eav_attribute_group table. Each group is connected to one parent attribute set.

Note: All non-trivial groups are related to the product and category entities. You can verify this by checking the table.

Entity Attribute Association

eav_entity_attribute Table

The association between attributes, entities, and groups is stored in the eav_entity_attribute table.

mysql> SELECT * FROM eav_entity_attribute WHERE entity_type_id=4 LIMIT 10;
+---------------------+----------------+------------------+--------------------+--------------+------------+
| entity_attribute_id | entity_type_id | attribute_set_id | attribute_group_id | attribute_id | sort_order |
+---------------------+----------------+------------------+--------------------+--------------+------------+
| 73                  | 4              | 4                | 7                  | 73           | 10         |
| 74                  | 4              | 4                | 7                  | 74           | 20         |
| 75                  | 4              | 4                | 13                 | 75           | 110        |
| 76                  | 4              | 4                | 13                 | 76           | 100        |
| 77                  | 4              | 4                | 7                  | 77           | 30         |
+---------------------+----------------+------------------+--------------------+--------------+------------+
⚠️ Denormalized Table: You may notice that this table is denormalized, since attribute_group_id carries information about attribute_set_id and entity_type_id.

Managing Attribute Sets

Attribute sets management can be done in two ways:

  1. Admin Panel: Stores → Attributes → Attribute Set
  2. Programmatically: Using code/data patches

Creating Attribute Sets Programmatically

⚠️ Subtle Detail to Be Aware Of: Normal attribute sets (for products) must include some attributes (like price) for a product to be functional. This means creating a new, empty attribute set is useless, unless we assign these attributes to it.
Solution: Create an attribute set "based" on another attribute set, which means attributes from the parent set will be copied to its children. This is done by the initFromSkeleton() method of the attribute set's model.

Example: Create Attribute Set Based on Another Set

<?php
namespace Vendor\Module\Setup\Patch\Data;

use Magento\Eav\Setup\EavSetup;
use Magento\Eav\Setup\EavSetupFactory;
use Magento\Framework\Setup\Patch\DataPatchInterface;
use Magento\Eav\Model\Entity\Attribute\SetFactory as AttributeSetFactory;
use Magento\Catalog\Model\Product;

class CreateCustomAttributeSet implements DataPatchInterface
{
    private $eavSetupFactory;
    private $attributeSetFactory;
    
    public function __construct(
        EavSetupFactory $eavSetupFactory,
        AttributeSetFactory $attributeSetFactory
    ) {
        $this->eavSetupFactory = $eavSetupFactory;
        $this->attributeSetFactory = $attributeSetFactory;
    }
    
    public function apply()
    {
        $eavSetup = $this->eavSetupFactory->create();
        $attributeSet = $this->attributeSetFactory->create();
        
        $entityTypeId = $eavSetup->getEntityTypeId(Product::ENTITY);
        
        // Get the default attribute set ID to use as skeleton
        $defaultSetId = $eavSetup->getDefaultAttributeSetId($entityTypeId);
        
        // Create new attribute set
        $attributeSet->setData([
            'attribute_set_name' => 'Custom Product Set',
            'entity_type_id' => $entityTypeId,
            'sort_order' => 100,
        ]);
        
        $attributeSet->validate();
        $attributeSet->save();
        
        // Copy attributes from default set (skeleton)
        $attributeSet->initFromSkeleton($defaultSetId);
        $attributeSet->save();
        
        return $this;
    }
    
    public static function getDependencies()
    {
        return [];
    }
    
    public function getAliases()
    {
        return [];
    }
}
Key Method: initFromSkeleton($skeletonId) copies all attributes from the skeleton (parent) attribute set to the new attribute set.

Types of Attributes in Magento

Attributes are a powerful feature in Magento. What makes them so powerful is that they go far beyond mere elements of data architecture. Attributes in Magento are functional - you can use them to change behavior of an object, not just add properties.

Two Primary Types:
  • EAV Attributes - Traditional entity-attribute-value attributes
  • Extension Attributes - Modern, flexible attributes for extending entities

EAV Attributes vs Extension Attributes

Feature EAV Attribute Extension Attribute
Applied to A Resource model that extends Magento\Eav\Model\Entity\AbstractEntity Data model that extends Magento\Framework\Api\AbstractExtensibleObject, or model that extends Magento\Framework\Model\AbstractExtensibleModel
Values stored In special tables with types *_entity_varchar, *_entity_int, etc. Example: catalog_product_entity_int Up to developer to decide where to store the data
Save and load Automatically implemented in AbstractEntity resource model. Lots of functionality in Magento_Catalog abstract resource model Manual. Developer has to load and save the data
Use for custom entity Very difficult Easy
Create new attribute Requires a DataPatch Requires an entry in etc/extension_attributes.xml file
Availability in WebAPI Available as Custom Attributes Available as Extension Attributes
Scope support Out of the box for product and category attributes Does not support scope out of the box, up to developer to implement
Grid and form support Yes, out-of-the-box No, requires custom work
Typical use case Extend an entity with a new scalar property, implement functionality when the property changes, support different values for different scopes Extend an entity with a new property, not necessarily scalar, could be an object or array. Data stored in custom tables, files, or fetched by API

When to Use EAV Attributes

Use EAV Attributes When:

  • ✅ Adding a simple scalar value (text, number, date) to products, categories, or customers
  • ✅ You need automatic save/load functionality
  • ✅ You need scope support (different values for website/store view)
  • ✅ You want the attribute to appear in admin grids and forms automatically
  • ✅ You need the attribute available in WebAPI as custom attributes
  • ✅ You want to implement functionality when the attribute changes
Example: Adding a "warranty_period" attribute to products with different values per store view.

When to Use Extension Attributes

Use Extension Attributes When:

  • ✅ Extending entities with complex data types (objects, arrays)
  • ✅ You need to store data in custom tables
  • ✅ Data comes from external sources (files, APIs)
  • ✅ You need fine control over data storage and retrieval
  • ✅ Extending non-EAV entities or custom entities
  • ✅ You don't need scope support
Example: Adding a "shipping_estimates" array to a quote, or "related_blog_posts" object to a product.

Creating EAV Attributes

EAV attributes require a DataPatch to create them programmatically.

Example: Product Attribute DataPatch

<?php
namespace Vendor\Module\Setup\Patch\Data;

use Magento\Eav\Setup\EavSetup;
use Magento\Eav\Setup\EavSetupFactory;
use Magento\Framework\Setup\Patch\DataPatchInterface;

class AddWarrantyAttribute implements DataPatchInterface
{
    private $eavSetupFactory;
    
    public function __construct(EavSetupFactory $eavSetupFactory)
    {
        $this->eavSetupFactory = $eavSetupFactory;
    }
    
    public function apply()
    {
        $eavSetup = $this->eavSetupFactory->create();
        
        $eavSetup->addAttribute(
            \Magento\Catalog\Model\Product::ENTITY,
            'warranty_period',
            [
                'type' => 'int',
                'label' => 'Warranty Period (months)',
                'input' => 'text',
                'required' => false,
                'sort_order' => 100,
                'global' => \Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface::SCOPE_STORE,
                'group' => 'General',
                'is_used_in_grid' => true,
                'is_visible_in_grid' => false,
                'is_filterable_in_grid' => true,
            ]
        );
        
        return $this;
    }
    
    public static function getDependencies()
    {
        return [];
    }
    
    public function getAliases()
    {
        return [];
    }
}

Creating Extension Attributes

Extension attributes require an entry in etc/extension_attributes.xml file.

Example: Adding Extension Attribute to Product

etc/extension_attributes.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:Api/etc/extension_attributes.xsd">
    <extension_attributes for="Magento\Catalog\Api\Data\ProductInterface">
        <attribute code="related_blog_posts" type="Vendor\Module\Api\Data\BlogPostInterface[]" />
    </extension_attributes>
</config>
⚠️ Remember: Unlike EAV attributes, extension attributes require manual implementation of data loading and saving through plugins or observers.

Key Differences Summary

EAV Attributes

Pros:

  • ✅ Automatic save/load
  • ✅ Scope support built-in
  • ✅ Grid/form support
  • ✅ WebAPI custom attributes

Cons:

  • ❌ Only scalar values
  • ❌ Difficult for custom entities
  • ❌ Performance overhead

Extension Attributes

Pros:

  • ✅ Complex data types (objects/arrays)
  • ✅ Custom storage
  • ✅ Easy for custom entities
  • ✅ Flexible implementation

Cons:

  • ❌ Manual save/load
  • ❌ No built-in scope support
  • ❌ No grid/form support

Exam Tips

Key Points to Remember

  • Attribute sets stored in eav_attribute_set table
  • Only products (entity_type_id=4) have multiple attribute sets
  • Attribute groups stored in eav_attribute_group - used for rendering only
  • Association table: eav_entity_attribute (denormalized)
  • initFromSkeleton() method copies attributes from parent set
  • New attribute sets must include required attributes (like price) to be functional
  • Two attribute types: EAV and Extension
  • EAV: Scalar values, automatic save/load, scope support, grid/form support
  • Extension: Complex types, manual save/load, custom storage, WebAPI
  • EAV creation: Requires DataPatch
  • Extension creation: Requires etc/extension_attributes.xml
  • EAV storage: *_entity_varchar, *_entity_int tables
  • Extension storage: Developer decides
  • WebAPI: EAV = Custom Attributes, Extension = Extension Attributes

Further Reading