Magento API 'Exception' 消息 'Item (Mage_Sales_Model_Order) with the same id "X" already exist'
Magento API 'Exception' with message 'Item (Mage_Sales_Model_Order) with the same id "X" already exist'
我正在尝试使用 Magento REST 获取订单列表 API。
我们使用的 REST 请求非常基本:http://www.example.com/api/rest/orders
响应显示下一个错误:
{
"messages": {
"error": [
{
"code": 0,
"message": "Item (Mage_Sales_Model_Order) with the same id \"54\" already exist"
}
]
}
}
检查我的异常日志以查看发生了什么并获得错误的下一个回溯:
2015-09-10T21:54:59+00:00 ERR (3):
exception 'Exception' with message 'Item (Mage_Sales_Model_Order) with the same id "54" already exist' in /path/to/site/lib/Varien/Data/Collection.php:373
Stack trace:
#0 /path/to/site/lib/Varien/Data/Collection/Db.php(576): Varien_Data_Collection->addItem(Object(Mage_Sales_Model_Order))
#1 /path/to/site/lib/Varien/Data/Collection.php(301): Varien_Data_Collection_Db->load()
#2 /path/to/site/app/code/core/Mage/Sales/Model/Api2/Order.php(302): Varien_Data_Collection->getItems()
#3 /path/to/site/app/code/core/Mage/Api2/Model/Resource.php(245): Mage_Sales_Model_Api2_Order->_retrieveCollection()
#4 /path/to/site/app/code/core/Mage/Api2/Model/Dispatcher.php(74): Mage_Api2_Model_Resource->dispatch()
#5 /path/to/site/app/code/core/Mage/Api2/Model/Server.php(239): Mage_Api2_Model_Dispatcher->dispatch(Object(Mage_Api2_Model_Request), Object(Mage_Api2_Model_Response))
#6 /path/to/site/app/code/core/Mage/Api2/Model/Server.php(107): Mage_Api2_Model_Server->_dispatch(Object(Mage_Api2_Model_Request), Object(Mage_Api2_Model_Response), Object(Mage_Api2_Model_Auth_User_Admin))
#7 /path/to/site/api.php(67): Mage_Api2_Model_Server->run()
#8 {main}
我修改了文件 app/code/core/Mage/Sales/Model/Api2/Order.php(函数 _retrieveCollection)并添加了一行以在日志中打印一些信息:
Mage::log($collection->getSelect(),null,'mylog.log');
这是输出的一部分:
[_parts:protected] => Array
(
[straightjoin] =>
[distinct] =>
[columns] => Array
(
[0] => Array
(
[0] => main_table
[1] => *
[2] =>
)
[1] => Array
(
[0] => payment_method
[1] => method
[2] => payment_method
)
[2] => Array
(
[0] => gift_message
[1] => sender
[2] => gift_message_from
)
[3] => Array
(
[0] => gift_message
[1] => recipient
[2] => gift_message_to
)
[4] => Array
(
[0] => gift_message
[1] => message
[2] => gift_message_body
)
[5] => Array
(
[0] => order_tax
[1] => title
[2] => tax_name
)
[6] => Array
(
[0] => order_tax
[1] => percent
[2] => tax_rate
)
)
[union] => Array
(
)
[from] => Array
(
[main_table] => Array
(
[joinType] => from
[schema] =>
[tableName] => sales_flat_order
[joinCondition] =>
)
[payment_method] => Array
(
[joinType] => left join
[schema] =>
[tableName] => sales_flat_order_payment
[joinCondition] => main_table.entity_id = payment_method.parent_id
)
[gift_message] => Array
(
[joinType] => left join
[schema] =>
[tableName] => gift_message
[joinCondition] => main_table.gift_message_id = gift_message.gift_message_id
)
[order_tax] => Array
(
[joinType] => left join
[schema] =>
[tableName] => sales_order_tax
[joinCondition] => main_table.entity_id = order_tax.order_id
)
)
[where] => Array
(
)
[group] => Array
(
)
[having] => Array
(
)
[order] => Array
(
)
[limitcount] =>
[limitoffset] =>
[forupdate] =>
)
[_tableCols:protected] => Array
(
)
)
如果我理解正确,那意味着 SQL 语句类似于:
SELECT
main_table.*,
payment_method.method AS method,
gift_message.sender AS gift_message_from,
gift_message.recipient AS gift_message_to,
gift_message.message AS gift_message_body,
order_tax.title AS tax_name,
order_tax.percent AS tax_rate
FROM
sales_flat_order AS main_table LEFT JOIN
sales_flat_order_payment AS payment_method ON main_table.entity_id = payment_method.parent_id LEFT JOIN
gift_message ON main_table.gift_message_id = gift_message.gift_message_id LEFT JOIN
sales_order_tax AS order_tax ON main_table.entity_id = order_tax.order_id
在手动 运行ning 上一个查询之后,它得出了不止一行具有相同 entity_id (sales_flat_order) 的行。这些 'duplicated' entity_id 行似乎是稍后使用 Varien_Data_Collection->addItem
时的问题
使具有相同 entity_id 的两行出现在结果集中的查询部分是 LEFT JOIN sales_order_tax。 table 包含的每个订单可以包含 N 行,因为每一行都包含应用的不同税收规则。
For example in Canada we collect two different Tax Rules combined for
some areas. In British Columbia we collect GST 5% (country specific)
plus PST 7% (province specific).
我是不是遗漏了一些明显的东西,还是我 运行 遇到了错误?
非常感谢任何帮助,感谢阅读!
P.S。我的问题与此处描述的问题非常接近:Magento API V2 Sales Orders List Not Working
经过一段时间的尝试,我想我找到了解决办法,所以我把它贴在这里以供将来参考。
解决方案
我们需要修改集合的查询,在开始迭代 Mage_Sales_Model_Api2_Order::_retrieveCollection 中的项目之前按 sales_flat_order.entity_id 分组。
由于修改核心文件不是一个好习惯,我们可以将核心 class 复制到本地代码池并根据需要进行修改。 Magento 将使用本地文件夹下的 class 覆盖核心 class.
- 复制app/code/core/Mage/Sales/Model/Api2/Order.php到app/code/local/Mage/Sales/Model/Api2/Order.php
- 修改本地代码池文件夹下的文件(app/code/local/Mage/Sales/Model/Api2)
- 查找函数 _retrieveCollection(Magento 1.9.2 中的第 288 行左右)
- 在
$this->_addTaxInfo($collection);
行之后,您应该添加:
$collection->getSelect()->group('main_table.entity_id');
缺点
如果我们正在更新 Magento,我们希望将 Mage_Sales_Model_Api2_Order class 的当前版本与新版本进行比较,如果我们发现差异,我们将重复制作副本的过程本地代码池文件夹下的core文件,重新编译
我正在尝试使用 Magento REST 获取订单列表 API。
我们使用的 REST 请求非常基本:http://www.example.com/api/rest/orders
响应显示下一个错误:
{
"messages": {
"error": [
{
"code": 0,
"message": "Item (Mage_Sales_Model_Order) with the same id \"54\" already exist"
}
]
}
}
检查我的异常日志以查看发生了什么并获得错误的下一个回溯:
2015-09-10T21:54:59+00:00 ERR (3):
exception 'Exception' with message 'Item (Mage_Sales_Model_Order) with the same id "54" already exist' in /path/to/site/lib/Varien/Data/Collection.php:373
Stack trace:
#0 /path/to/site/lib/Varien/Data/Collection/Db.php(576): Varien_Data_Collection->addItem(Object(Mage_Sales_Model_Order))
#1 /path/to/site/lib/Varien/Data/Collection.php(301): Varien_Data_Collection_Db->load()
#2 /path/to/site/app/code/core/Mage/Sales/Model/Api2/Order.php(302): Varien_Data_Collection->getItems()
#3 /path/to/site/app/code/core/Mage/Api2/Model/Resource.php(245): Mage_Sales_Model_Api2_Order->_retrieveCollection()
#4 /path/to/site/app/code/core/Mage/Api2/Model/Dispatcher.php(74): Mage_Api2_Model_Resource->dispatch()
#5 /path/to/site/app/code/core/Mage/Api2/Model/Server.php(239): Mage_Api2_Model_Dispatcher->dispatch(Object(Mage_Api2_Model_Request), Object(Mage_Api2_Model_Response))
#6 /path/to/site/app/code/core/Mage/Api2/Model/Server.php(107): Mage_Api2_Model_Server->_dispatch(Object(Mage_Api2_Model_Request), Object(Mage_Api2_Model_Response), Object(Mage_Api2_Model_Auth_User_Admin))
#7 /path/to/site/api.php(67): Mage_Api2_Model_Server->run()
#8 {main}
我修改了文件 app/code/core/Mage/Sales/Model/Api2/Order.php(函数 _retrieveCollection)并添加了一行以在日志中打印一些信息:
Mage::log($collection->getSelect(),null,'mylog.log');
这是输出的一部分:
[_parts:protected] => Array
(
[straightjoin] =>
[distinct] =>
[columns] => Array
(
[0] => Array
(
[0] => main_table
[1] => *
[2] =>
)
[1] => Array
(
[0] => payment_method
[1] => method
[2] => payment_method
)
[2] => Array
(
[0] => gift_message
[1] => sender
[2] => gift_message_from
)
[3] => Array
(
[0] => gift_message
[1] => recipient
[2] => gift_message_to
)
[4] => Array
(
[0] => gift_message
[1] => message
[2] => gift_message_body
)
[5] => Array
(
[0] => order_tax
[1] => title
[2] => tax_name
)
[6] => Array
(
[0] => order_tax
[1] => percent
[2] => tax_rate
)
)
[union] => Array
(
)
[from] => Array
(
[main_table] => Array
(
[joinType] => from
[schema] =>
[tableName] => sales_flat_order
[joinCondition] =>
)
[payment_method] => Array
(
[joinType] => left join
[schema] =>
[tableName] => sales_flat_order_payment
[joinCondition] => main_table.entity_id = payment_method.parent_id
)
[gift_message] => Array
(
[joinType] => left join
[schema] =>
[tableName] => gift_message
[joinCondition] => main_table.gift_message_id = gift_message.gift_message_id
)
[order_tax] => Array
(
[joinType] => left join
[schema] =>
[tableName] => sales_order_tax
[joinCondition] => main_table.entity_id = order_tax.order_id
)
)
[where] => Array
(
)
[group] => Array
(
)
[having] => Array
(
)
[order] => Array
(
)
[limitcount] =>
[limitoffset] =>
[forupdate] =>
)
[_tableCols:protected] => Array
(
)
)
如果我理解正确,那意味着 SQL 语句类似于:
SELECT
main_table.*,
payment_method.method AS method,
gift_message.sender AS gift_message_from,
gift_message.recipient AS gift_message_to,
gift_message.message AS gift_message_body,
order_tax.title AS tax_name,
order_tax.percent AS tax_rate
FROM
sales_flat_order AS main_table LEFT JOIN
sales_flat_order_payment AS payment_method ON main_table.entity_id = payment_method.parent_id LEFT JOIN
gift_message ON main_table.gift_message_id = gift_message.gift_message_id LEFT JOIN
sales_order_tax AS order_tax ON main_table.entity_id = order_tax.order_id
在手动 运行ning 上一个查询之后,它得出了不止一行具有相同 entity_id (sales_flat_order) 的行。这些 'duplicated' entity_id 行似乎是稍后使用 Varien_Data_Collection->addItem
使具有相同 entity_id 的两行出现在结果集中的查询部分是 LEFT JOIN sales_order_tax。 table 包含的每个订单可以包含 N 行,因为每一行都包含应用的不同税收规则。
For example in Canada we collect two different Tax Rules combined for some areas. In British Columbia we collect GST 5% (country specific) plus PST 7% (province specific).
我是不是遗漏了一些明显的东西,还是我 运行 遇到了错误?
非常感谢任何帮助,感谢阅读!
P.S。我的问题与此处描述的问题非常接近:Magento API V2 Sales Orders List Not Working
经过一段时间的尝试,我想我找到了解决办法,所以我把它贴在这里以供将来参考。
解决方案
我们需要修改集合的查询,在开始迭代 Mage_Sales_Model_Api2_Order::_retrieveCollection 中的项目之前按 sales_flat_order.entity_id 分组。
由于修改核心文件不是一个好习惯,我们可以将核心 class 复制到本地代码池并根据需要进行修改。 Magento 将使用本地文件夹下的 class 覆盖核心 class.
- 复制app/code/core/Mage/Sales/Model/Api2/Order.php到app/code/local/Mage/Sales/Model/Api2/Order.php
- 修改本地代码池文件夹下的文件(app/code/local/Mage/Sales/Model/Api2)
- 查找函数 _retrieveCollection(Magento 1.9.2 中的第 288 行左右)
- 在
$this->_addTaxInfo($collection);
行之后,您应该添加:$collection->getSelect()->group('main_table.entity_id');
缺点
如果我们正在更新 Magento,我们希望将 Mage_Sales_Model_Api2_Order class 的当前版本与新版本进行比较,如果我们发现差异,我们将重复制作副本的过程本地代码池文件夹下的core文件,重新编译