Dropdown product attributes: int vs. varchar
-
16-10-2019 - |
Question
For an attribute set up as a dropdown, is that supposed to be an int
or a varchar
?
I'm fixing a catalog of products that someone else imported, and I'm seeing a size attribute set up as a dropdown as an int
type (backend
column in eav_attributes
), but the integer values are stored in the catalog_product_entity_varchar
table. So, the simple products think they have no sizes assigned.
Furthermore, I thought if the varchar EAV table had dropdown values, it stored it as a string, not an integer that points to the EAV table. I've seen a dropdown attribute stored its values in the ..._varchar
table as actual strings values and not a number that refered back to the eav attriute table because it was created as a varchar
during an extension installation.
So, my questions are..
A dropdown attribute gets a backend type of
int
if created in the admin, but if you create an attribute via an extension, you can install this column as avarchar
. Does it really matter if a dropdown attribute is anint
or avarchar
type?Regarding the catalog that I'm fixing, I'm not quite sure what the original developer did. He didn't use a text file to import the products; from the scripts I have that were used in the product import, he programmatically saved the products with data he had (i.e. via
$product->save()
). But how did this dropdown attribute get created as anint
backend but ended up in thecatalog_product_entity_varchar
table with numerical strings that point toeav_attribute_option
. I did verified these "varchar" values point to actual entries ineav_attribute_option
.IF the dropdown attribute was setup as a
varchar
backend type, how does Magento know to refer to the EAV options with the numerical varchar values instead of just assigning the attribute value as "1" or "2" (as in size 1, 2, etc. instead of Small, Medium, etc.)? I'm assuming this is because it was set up as a dropdown, but just wanted to check.
Solution
Let's take them one by one.
You should use the
int
values for consistency. But (as you saw) it works withvarchar
also. I have a hunch it works withtext
too."how did this dropdown attribute get created as an int backend but ended up in the catalog_product_entity_varchar". That's a complete mystery. Only the original developer can tell you that (maybe not even him). But I can tell you how is possible to reference the
eav_attribute_option
table. It's because the attribute options do not care about the type of the attribute. If the attribute has asource_model
it callsgetAllOptions
from that source model and matches the value set on the product with what it finds in the result ofgetAllOptions
.I think the answer to number 2 will answer number 3 also. In addition is because PHP is a loose type programming language and
3 == "3"
evaluates totrue
.
OTHER TIPS
In addition to Marius' answer, - I'm not 100% sure about this - I think if you programmatically create a dropdown attribute as type varchar
and add options, but later you save the attribute through the admin (Catalog -> Attributes -> Manage Attributes), it changes the type from varchar
to int
. That way you end up with an attribute with type int
, but with it's values actually stored in the catalog_product_entity_varchar
table.
A weird side effect of this is that some things continue to work normally, but once you do addAttributeToFilter
, it won't give you any results any more.
edit: I just tested this and it's like I described above. If you save an attribute with input
as select
through the admin area, it will change the type
to int
, even if it was varchar
before. For some reason all labels/options still work, but filtering stops working because it's looking in the wrong table for values.
I encountered the same problem with a custom import module. The attributes were created with dropdown and backend type 'varchar'. The products were setup fine in backend but would not show up on frontend categories.
It only worked when we redid the import, with attributes having backend type 'int'. Now the products show up fine, and attribute values show up in the '_int' table.