Magento 开发笔记5
在任何一个快速迭代的工程下,如何保证开发和生产(现网)数据库同步是一个很头疼的事情。Magento提供了一个创建资源迁移版本的系统,可以帮助我们处理开发过程中不断遇到的这个问题。www.2cto.com
上次我们创建了weblogpost的模型。这次,我们执行直接执行CREATE TABLE。我们将未我们的module创建一个Setup Resource,而该资源会创建一个表格。我们同时也会创建一个升级的脚本,它能升级已经安装的module。总的来说
1. 在config里增加SetupResource
2. 创建resourceclass文件
3. 创建installerscript
4. 创建升级script
增加Setup Resource
我们在
增加完配置后,清除cache,并且加载Magento Site,你会发现出异常了
Fatalerror: Class 'XStarX_Weblog_Model_Resource_Mysql4_Setup' not found in
Magento试图实例化我们在config里声明的类,但是没有找到。我们需要创建这样的类文件app/code/local/XStarX/Weblog/Model/Resource/Mysql4/Setup.php
classXStarX_Weblog_Model_Resource_Mysql4_Setup extendsMage_Core_Model_Resource_Setup { }
现在重新加载Magento网站,异常就消失了。
创建安装脚本
接下来,我们要创建安装脚本。脚本包含了之前的CREATETABLE语句。
首先,先看一下config.xml
这个部分在配置文件中是必备的,标示了module的同时也告诉了版本。安装脚本要基于版本好。在下列位置创建文件
app/code/local/XStarX/Weblog/sql/weblog_setup/mysql4-install-0.1.0.php
echo 'Running This Upgrade: '.get_class($this)."\n
\n";
die("Exit for now");
路径的weblog_setup部分匹配了config.xml文件
Running This Upgrade:Alanstormdotcom_Weblog_Model_Resource_Mysql4_Setup Exit for now ...
这意味着我们的update脚本执行了。最终我们把SQL更新文件放在这里,但是暂时我们把精力放在setup机制上。把die声明去掉,
echo 'Running This Upgrade:'.get_class($this)."\n
\n";
重新加载页面,可以看到升级消息在页面的首部分展示。重新加载,页面将恢复正常。因为setup就一次嘛。不可能总setup。
创建安装脚本
MagenoSetup Resources容许我们简单的放置安装脚本和升级脚本,然后系统就会自动执行。这容许我们系统中的数据迁移脚本保持一次。
使用database client,查看core_resroucetable
mysql> select * from core_resource;
+-------------------------+---------+ |code | version |+-------------------------+-----+
|adminnotification_setup | 1.0.0 |
| admin_setup | 0.7.1 |
| amazonpayments_setup | 0.1.2 |
| api_setup | 0.8.1 |
| backup_setup | 0.7.0 |
| bundle_setup | 0.1.7 |
| catalogindex_setup | 0.7.10 |
| cataloginventory_setup | 0.7.5 |
| catalogrule_setup | 0.7.7 |
| catalogsearch_setup | 0.7.6 |
| catalog_setup | 0.7.69 |
| checkout_setup | 0.9.3 |
| chronopay_setup | 0.1.0 |
| cms_setup | 0.7.8 |
| compiler_setup | 0.1.0 |
| contacts_setup | 0.8.0 |
| core_setup | 0.8.13 |
| cron_setup | 0.7.1 |
| customer_setup | 0.8.11 |
| cybermut_setup | 0.1.0 |
| cybersource_setup | 0.7.0 |
| dataflow_setup | 0.7.4 |
| directory_setup | 0.8.5 |
| downloadable_setup | 0.1.14 |
| eav_setup | 0.7.13 |
| eway_setup | 0.1.0 |
| flo2cash_setup | 0.1.1 |
| giftmessage_setup |0.7.2 |
| googleanalytics_setup | 0.1.0 |
| googlebase_setup | 0.1.1 |
| googlecheckout_setup | 0.7.3 |
| googleoptimizer_setup | 0.1.2 |
| ideal_setup | 0.1.0 |
| log_setup | 0.7.6 |
| newsletter_setup | 0.8.0 |
| oscommerce_setup | 0.8.10 |
| paybox_setup | 0.1.3 |
| paygate_setup | 0.7.0 |
| payment_setup | 0.7.0 |
| paypaluk_setup | 0.7.0 |
| paypal_setup | 0.7.2 |
| poll_setup | 0.7.2 |
| productalert_setup | 0.7.2 |
| protx_setup | 0.1.0 |
| rating_setup | 0.7.2 |
| reports_setup | 0.7.7 |
| review_setup | 0.7.4 |
| salesrule_setup | 0.7.7 |
| sales_setup | 0.9.38 |
| sendfriend_setup | 0.7.2 |
| shipping_setup | 0.7.0 |
| sitemap_setup | 0.7.2 |
| strikeiron_setup | 0.9.1 |
| tag_setup | 0.7.2 |
| tax_setup | 0.7.8 |
| usa_setup | 0.7.0 |
| weblog_setup | 0.1.0 |
| weee_setup | 0.13 |
| wishlist_setup | 0.7.4 |
+-------------------------+---------+ 59 rowsin set (0.00 sec)
这个表格包含了所有安装module的list,同时还有对应的版本。在表的结尾部分看到了
| weblog_setup | 0.1.0 |
这个就是Magento如何知道要不要重新执行脚本。如果都成功,页面就会加载。Weblog_setup已经安装了,所以不需要更新。如果想重装脚本,需要删除表里的改行。我们现在可以删除
DELETE from core_resource where code = 'weblog_setup';
然后删除对应的table
DROP TABLE blog_posts;
接着在setup脚本里增加
$installer = $this;
$installer->startSetup();
$installer->run("
CREATE TABLE `{
$installer->getTable('weblog/blogpost')}`(
`blogpost_id`int(11) NOT NULL auto_increment,
`title`text,
`post`text,
`date`datetime default NULL,
`timestamp`timestamp NOT NULL default CURRENT_TIMESTAMP, PRIMARY KEY (`blogpost_id`) )
ENGINE=InnoDBDEFAULT CHARSET=utf8;
INSERTINTO `{$installer->getTable('weblog/blogpost')}` VALUES (1,'My NewTitle','This is a blog post','2009-07-01 00:00:00','2009-07-02 23:12:30'); ");
$installer->endSetup();
清除cache,加载页面,你可以看到blog_posts又创建了,并且有一条数据。
创建安装脚本---问题
上面的安装可能不会那么顺利,在magento1.7下面会报错
Mage_Eav_Exception: Can't create table: module_entity
如何解决呢?
Debug createEntityTables()方法,可以在结尾处看到
$connection->beginTransaction(); try { foreach ($tables as $tableName => $table) { $connection->createTable($table); } $connection->commit(); } catch (Exception $e) { Zend_Debug::dump($e->getMessage()); $connection->rollBack(); throw Mage::exception('Mage_Eav', Mage::helper('eav')->__('Can\'t create table: %s', $tableName)); }
查看底层错误是:UserError: DDL statements are not allowed in transactions
然后跟进commit函数
/** * Check transaction level in case of DDL query * * @param string|Zend_Db_Select $sql * @throws Zend_Db_Adapter_Exception */ protected function _checkDdlTransaction($sql) { if (is_string($sql) && $this->getTransactionLevel() > 0) { $startSql = strtolower(substr(ltrim($sql), 0, 3)); if (in_array($startSql, $this->_ddlRoutines)) { trigger_error(Varien_Db_Adapter_Interface::ERROR_DDL_MESSAGE, E_USER_ERROR); } } }
结论是Mysql不支持DDL Transaction。
因此在app/code/local/{CompanyName}/{ModuleName}/Setup/Helper.php里重写createEntityTable方法
{ ... /** * Remove transaction code due to issues with errors. */ //$connection->beginTransaction(); try { foreach ($tables as $tableName => $table) { $connection->createTable($table); } $connection->commit(); } catch (Exception $e) { //$connection->rollBack(); throw Mage::exception('Mage_Eav', Mage::helper('eav')->__('Can\'t create table: %s', $tableName)); } } }
然后问题解决。
Setup脚本剖析
让我们一行一行的解释。首先
$installer = $this;
每个安装脚本都是从SetResource类开始执行的(就是我们上面创建的)。这意味着脚本中的$this引用是这个类实例化的引用。如果不是必须,core系统里大部分安装脚本都是把$this命名未installer,此处我们也是这样。
接下来我们看到了两个方法
$installer->startSetup();
//...
$installer->endSetup();
如果查看Mage_Core_Model_Resource_Setup类(在目录app/code/core/Mage/Core/Resource/Setup.php),你可以看到如下的内容
public function startSetup()
{
$this->_conn->multi_query("
SET SQL_MODE='';
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO'; ");
return $this;
}
public function endSetup()
{
$this->_conn->multi_query("
SET SQL_MODE=IFNULL(@OLD_SQL_MODE,'');
SET FOREIGN_KEY_CHECKS=IFNULL(@OLD_FOREIGN_KEY_CHECKS,0); ");
return $this;
}
最后我们执行
$installer->run(...);
这个接受了一个包含创建数据库的SQL。你可定义任意的查询,通过分号隔开就好。同时,也要注意
$installer->getTable('weblog/blogpost')
getTable方法容许我们把Magento Model URI传入,然后得到它的表名。如果不是必要,就用次方法执行。Mage_Core_Model_Resource_Setup类包含了很多有用的Helper方法。最有效的学习是研究Magento core的installer scripts。
Module升级
上面讲述了如何初始化数据表,但是如何改变现有墨香的结构呢?Magento的Setup Resources支持一个简单的版本策略,可以让我们自动的执行脚本来升级我们的模块。
一旦Magento执行一个安装脚本后,它就不会再次执行另外一个安装脚本。这个时候,我们应该创建一个升级脚本。升级脚本跟安装脚本非常类似,只有有些关键处不一样。
作为开始,我们在下列位置创建一个脚本,
XStarX/Weblog/sql/weblog_setup/mysql4-upgrade-0.1.0-0.2.0.php
echo 'Testing our upgrade script (mysql4-upgrade-0.1.0-0.2.0.php) and halting execution to avoid updating the system version number
';
die();
升级脚本和安装脚本在同一个目录,但是略有不同。首先,文件名要包含upgrade。其次,要有两个版本号,并用“-”分隔。第一个是升级的源版本,第二个是升级的目标版本。
清除cache后,重新加载页面,但这个时候脚本并没有执行。我们需要更新config.xml里面的版本信息来触发升级
写入新的版本号后,如果清除缓存,加载网站,就可以看到输出了。这个时候还有一个关键点需要注意,所以先不慌做这一步。我们在同样的目录创建另外一个文件
XStarX/Weblog/sql/weblog_setup/mysql4-upgrade-0.1.0-0.1.5.php
echo 'Testing our upgrade script (mysql4-upgrade-0.1.0-0.1.5.php) and NOT halting execution
';
这个时候再清除缓存,加载页面,可以看到两个信息。当Magento发现版本号信息变更后,他会执行所有可执行的脚本来更新模块。尽管我们从没有创建0.1.5版本,但是Magento会看到升级脚本,然后尝试执行。脚本一般按照从低到高的顺序执行。下面的数据会说明这个
mysql> select * from core_resource where code = 'weblog_setup'; +--------------+---------+
| code | version | +--------------+---------+
| weblog_setup | 0.1.5 | +--------------+---------+
1 row in set (0.00 sec)
我们看到数据表里的版本是1.5。这是因为我们从1.0到1.5升级,但是没有执行1.0到2.0的升级。好了,说明了这个关键问题后,我们言归正传。回到脚本上来,先修改升级脚本0.1.0-0.2.0
$installer = $this;
$installer->startSetup();
$installer->run("
ALTER TABLE `{$installer->getTable('weblog/blogpost')}`
CHANGE post post text not null; ");
$installer->endSetup();
die("You'll see why this is here in a second");
刷新页面,但是什么也不会发生。升级脚本为什么没有执行?
1. weblog_setup resource是版本0.1.0
2. 我们要升级模块到0.2.0
3. Magento看到升级模块,有两个脚本要执行,0.1.0-0.1.5 和0.1.0-0.2.0
4. Magento载入队列,然后执行
5. Magento执行0.1.0到0.1.5的脚本
6. Weblog_setup resource现在是0.1.5了
7. Magento执行0.1.0到0.2.0的脚本,执行停止
8. 在下一个页面加载的时候,Magento看到了weblog_set在版本0.1.5,但是并没有看到任何从0.1.5开始执行的脚本(之前的都是0.1.0开始)
正确的方式如下,重新命名文件
mysql4-upgrade-0.1.0-0.1.5.php #This goes from 0.1.0 to 0.1.5
mysql4-upgrade-0.1.5-0.2.0.php #This goes 0.1.5 to 0.2.0
Magento是能够完成一次加载两次升级的。你可以清除core_resource表信息,来完成最后的test
update core_resource set version = '0.1.0' where code = 'weblog_setup';
Magento是根据配置文件来执行升级的,所以在协同开发时要注意脚本的添加。

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

AIxiv专栏是本站发布学术、技术内容的栏目。过去数年,本站AIxiv专栏接收报道了2000多篇内容,覆盖全球各大高校与企业的顶级实验室,有效促进了学术交流与传播。如果您有优秀的工作想要分享,欢迎投稿或者联系报道。投稿邮箱:liyazhou@jiqizhixin.com;zhaoyunfeng@jiqizhixin.com在人工智能领域的发展过程中,对大语言模型(LLM)的控制与指导始终是核心挑战之一,旨在确保这些模型既强大又安全地服务于人类社会。早期的努力集中于通过人类反馈的强化学习方法(RL

如果AI模型给的答案一点也看不懂,你敢用吗?随着机器学习系统在更重要的领域得到应用,证明为什么我们可以信任它们的输出,并明确何时不应信任它们,变得越来越重要。获得对复杂系统输出结果信任的一个可行方法是,要求系统对其输出产生一种解释,这种解释对人类或另一个受信任的系统来说是可读的,即可以完全理解以至于任何可能的错误都可以被发现。例如,为了建立对司法系统的信任,我们要求法院提供清晰易读的书面意见,解释并支持其决策。对于大型语言模型来说,我们也可以采用类似的方法。不过,在采用这种方法时,确保语言模型生

AIxiv专栏是本站发布学术、技术内容的栏目。过去数年,本站AIxiv专栏接收报道了2000多篇内容,覆盖全球各大高校与企业的顶级实验室,有效促进了学术交流与传播。如果您有优秀的工作想要分享,欢迎投稿或者联系报道。投稿邮箱:liyazhou@jiqizhixin.com;zhaoyunfeng@jiqizhixin.com这篇论文的作者均来自伊利诺伊大学香槟分校(UIUC)张令明老师团队,包括:StevenXia,四年级博士生,研究方向是基于AI大模型的自动代码修复;邓茵琳,四年级博士生,研究方

同样是图生视频,PaintsUndo走出了不一样的路线。ControlNet作者LvminZhang又开始整活了!这次瞄准绘画领域。新项目PaintsUndo刚上线不久,就收获1.4kstar(还在疯狂涨)。项目地址:https://github.com/lllyasviel/Paints-UNDO通过该项目,用户输入一张静态图像,PaintsUndo就能自动帮你生成整个绘画的全过程视频,从线稿到成品都有迹可循。绘制过程,线条变化多端甚是神奇,最终视频结果和原图像非常相似:我们再来看一个完整的绘

干杯!当论文讨论细致到词句,是什么体验?最近,斯坦福大学的学生针对arXiv论文创建了一个开放讨论论坛——alphaXiv,可以直接在任何arXiv论文之上发布问题和评论。网站链接:https://alphaxiv.org/其实不需要专门访问这个网站,只需将任何URL中的arXiv更改为alphaXiv就可以直接在alphaXiv论坛上打开相应论文:可以精准定位到论文中的段落、句子:右侧讨论区,用户可以发表问题询问作者论文思路、细节,例如:也可以针对论文内容发表评论,例如:「给出至

当前,采用下一token预测范式的自回归大型语言模型已经风靡全球,同时互联网上的大量合成图像和视频也早已让我们见识到了扩散模型的强大之处。近日,MITCSAIL的一个研究团队(一作为MIT在读博士陈博远)成功地将全序列扩散模型与下一token模型的强大能力统合到了一起,提出了一种训练和采样范式:DiffusionForcing(DF)。论文标题:DiffusionForcing:Next-tokenPredictionMeetsFull-SequenceDiffusion论文地址:https:/

最近,被称为千禧年七大难题之一的黎曼猜想迎来了新突破。黎曼猜想是数学中一个非常重要的未解决问题,与素数分布的精确性质有关(素数是那些只能被1和自身整除的数字,它们在数论中扮演着基础性的角色)。在当今的数学文献中,已有超过一千条数学命题以黎曼猜想(或其推广形式)的成立为前提。也就是说,黎曼猜想及其推广形式一旦被证明,这一千多个命题将被确立为定理,对数学领域产生深远的影响;而如果黎曼猜想被证明是错误的,那么这些命题中的一部分也将随之失去其有效性。新的突破来自MIT数学教授LarryGuth和牛津大学

把因果链展示给LLM,它就能学会公理。AI已经在帮助数学家和科学家做研究了,比如著名数学家陶哲轩就曾多次分享自己借助GPT等AI工具研究探索的经历。AI要在这些领域大战拳脚,强大可靠的因果推理能力是必不可少的。本文要介绍的这项研究发现:在小图谱的因果传递性公理演示上训练的Transformer模型可以泛化用于大图谱的传递性公理。也就是说,如果让Transformer学会执行简单的因果推理,就可能将其用于更为复杂的因果推理。该团队提出的公理训练框架是一种基于被动数据来学习因果推理的新范式,只有演示
