在进入细节之前,让我们清楚地提出问题:
通过 hard 我的意思是,从数据库中删除行,而不仅仅是将值设置为null或为空。
我目前面临着Magento的问题。
我商店中的许多产品都具有与产品无关的用户定义属性。例如,我们假设我们有一个 bag 产品,以及其他产品,如 T恤,连衣裙,裤子等:
我们的包产品只有可配置的1个属性:颜色。
我们的 T恤产品有2个可配置属性:颜色和 tshirt_size 。
我们的连衣裙产品有2个可配置属性:颜色和 dress_size
我目前的问题是,当我从数据库中检索 Bag 产品时,我产品中存储的属性为:颜色, tshirt_size 和 dress_size 。
我怀疑这是因为在我们的商店中您可以更改产品的属性集(感谢FlagBit ChangeAttributeSet社区扩展)。
我认为包产品是使用特定的属性集创建的,然后有人将属性集更改为另一个,另一个更改。这将导致产品从所有已更改的属性集中获取所有属性。但这仅仅是一个,而这可能是另一个原因。我实际上目前没有找到导致我的产品具有不相关属性的具体原因。
我今天想重置我的产品。通过重置我的意思是删除与我的产品无关的属性。对于我的 bag ,这意味着删除 tshirt_size 和 dress_size 属性。通过删除,我的意思是从对象中永久删除这些属性。
我的问题是,我无法找到如何做到这一点。我尝试将属性设置为NULL并保存产品,但是当我再次查询产品时,我仍然获得数据中的属性,其值为null。我不希望属性值为null,我希望该属性不存在。
以下是一段代码示例,解释了我尝试的内容:
$product = Mage::getModel('catalog/product')->load(1234); //Let's assume that my bag product ID is 1234
Mage::log($product->getData());
/* This last line dump all my products datas and contains among other things:
[...]=>...
[color]=>3
[tshirt_size]=>34
[dress_size]=>45
[...]=>...
*/
如果我这样做:
$product->setData('tshirt_size',null);
$product->setData('dress_size',null);
$product->save();
然后再次:
$product = Mage::getModel('catalog/product')->load(1234);
Mage::log($product->getData());
/* I get:
[...]=>...
[color]=>3
[tshirt_size]=>null
[dress_size]=>null
[...]=>...
*/
我不想要那个。我想要:
/*
[...]=>...
[color]=>3
[...]=>...
*/
我仍然拥有数组中的条目这意味着数据库中的实际行不会被删除。我希望删除行。
当我做的时候更令人沮丧:
$product->getAttributes();
它返回了我可以设置到我的产品的所有属性没有不相关的属性 - 这是有道理的,因为不相关的属性不在我的产品的属性集中。
所以,问题是:
通过 hard 我的意思是,从数据库中删除行,而不仅仅是将值设置为null或为空。
感谢您的帮助!
雨果。
仅供参考:我使用Magento 1.6.1.0(但它并没有真正改变任何东西)
答案 0 :(得分:2)
我最终不得不解决这个问题,虽然@vBuck很接近,但我总是可以在属性集中切换后查询旧数据,如果我切换回来,我会看到旧数据时它不应该是我去过那儿。今天,我同样需要确保删除随机数据。以下是我如何处理这个话题。
为了在从一个集合切换到另一个集合时以编程方式删除属性,您必须首先查看新集合的所有条目,然后获取所有属性的列表,检查该列表并且(这是重要部分)从正确的实体表中删除它。例如,当我将500 GB
从Western Digital 500GB HD - 7200RPM
切换到Hard Drive
时,我希望摆脱示例Magento数据中Shoes
的值。为此,我必须删除它所存储的catalog_product_entity_text
表中的条目。这意味着我必须找到与产品ID相等的条目,然后将其从其实体类型表中删除。
我能够做到这一点,之后无法找到迷路数据。数据库搜索和切换回旧属性集并查找数据都证实了这一点。你可以在这里找到它
https://gist.github.com/jeremyBass/6581038#file-attribute-clean-switch-md
在CE 1.7.0.2,1.8.0.0
中测试答案 1 :(得分:1)
所以我也很想得到程序化的答案,但我没有时间去做。但这是我可以为这个链提供的。当您尝试从管理员中删除属性时,您会看到所需的结果操作。
<强>步骤:强>
似乎当我从集合中移除attr之前没有清除所有的attrs时,结果是应用程序将行留在那里。也许是为了安全起见,我不知道,因为我没有潜入。我可以告诉我的是,如果你没有清除attr从集合中移除之前的值,当你设置attr为null,attr仍然存在。
那么,程序化解决方案将需要遵循这种模式。如果我有时间,我会写它,但我现在已经在队列中完成了15个其他任务。
答案 2 :(得分:0)
好的,我终于在提问后15分钟找到了(并花了几个小时试图解决它)
以下是答案:
$product = Mage::getModel('catalog/product')->load(1234); //Let's assume that my bag product ID is 1234
$product->setData('unwanted_attribute',null);
$resource = $product->getResource();
$resource->saveAttribute($product,'unwanted_attribute');
$product->save()
重新保存产品,则会重新显示所有属性。答案 3 :(得分:0)
看起来这是一篇旧帖子,但我也在寻找答案,我想我已经找到了解决方案。
要解决这个问题,我必须直接使用产品资源的写适配器:
$product->getResource()->getWriteConnection()
从表中删除属性值。
我在挖掘一些代码后得到了如何做到这一点的线索。见Mage_Catalog_Model_Resource_Eav_Mysql4_Abstract::_saveAttributeValue
:
$write = $this->_getWriteAdapter();
$storeId = Mage::app()->getStore($object->getStoreId())->getId();
$table = $attribute->getBackend()->getTable();
/**
* If we work in single store mode all values should be saved just
* for default store id
* In this case we clear all not default values
*/
if (Mage::app()->isSingleStoreMode()) {
$storeId = $this->getDefaultStoreId();
$write->delete($table, join(' AND ', array(
$write->quoteInto('attribute_id=?', $attribute->getAttributeId()),
$write->quoteInto('entity_id=?', $object->getEntityId()),
$write->quoteInto('store_id<>?', $storeId)
)));
}
在更改属性集之前,通过$product->getAttributes()
循环使用此代码,您可以在不破坏属性本身的情况下从产品属性中“取消链接”值。然后你可以安全地更改属性集(如在Flagbit的扩展名中所做的那样),而不是留下死数据。
使用上面的代码,这是我为证明我的理论而写的一个演示:
$product=Mage::getModel('catalog/product')->load(MY_TARGET_PRODUCT_ID);
$write=$product->getResource()->getWriteConnection();
foreach($product->getAttributes() as $attribute) {
if($attribute->getId()==MY_TARGET_ATTRIBUTE_ID) {
$write->delete(
$attribute->getBackend()->getTable(),
join(' AND ', array(
$write->quoteInto('attribute_id=?',$attribute->getAttributeId()),
$write->quoteInto('entity_id=?',$product->getId())
))
);
}
}
在此示例中,我正在寻找要从产品中清除的特定属性,但您可以删除IF
条件以删除每个附加值。
我还没有完全测试过这个,但到目前为止似乎还不错。顺便说一句,我正在运行Magento 1.4。希望它可以帮助别人!
<强>更新强>
看起来上面只有一半是正确的。您仍然必须小心不要清除可能导致产品死亡的某些属性(例如名称,模式,状态等)。所以在我的情况下,看起来我必须在删除之前与默认属性集进行比较。
另一个更新:
在此SO帖子的帮助下:https://stackoverflow.com/a/8500506/1442685 我能够比较链接到产品的所有属性,并仅删除非默认值。这样,在更改集合时,我可以确保不会丢失有关产品的基本信息。查看我的Gist,了解这两个课程的完成情况:
答案 4 :(得分:-1)
你应该可以像以下任何一个一样取消设置值:
$product->unsetData('unwanted_attribute')
->save();
$product->unsUnwantedAttribute()
->save();
答案 5 :(得分:-1)
您需要转到管理员&gt;&gt;目录&gt;&gt;属性&gt;&gt;管理属性集 如果您尝试管理产品目录,则应首先考虑您的属性(与您的产品分开),然后再考虑您的产品(实际上并不是产品的一部分)。 正确建立属性和属性集后,可以将它们应用于具有每个属性值的产品。
或者您更喜欢这种事情?
class Mage_catalog_Model_Product_Attribute_Set_Api extends Mage_Api_Model_Resource_Abstract
{
{
/**
* Retrieve attribute set list
*
* @return array
*/
public function items()
{
$entityType = Mage::getModel('catalog/product')->getResource()->getEntityType();
$collection = Mage::getResourceModel('eav/entity_attribute_set_collection')
->setEntityTypeFilter($entityType->getId());
$result = array();
foreach ($collection as $attributeSet) {
$result[] = array(
'set_id' => $attributeSet->getId(),
'name' => $attributeSet->getAttributeSetName()
);
}
return $result;
}
} // Class Mage_Catalog_Model_Product_Attribute_Set_Api End
答案 6 :(得分:-3)
将属性集关联到产品后,无法更改属性集或删除该属性集。
出路是导出产品然后修改工作表并导入。
此链接还说明: https://collaborate.magento.com/magento/topics/how_do_i_change_product_attribute_set