Magento安装脚本中的ALTER TABLE,而不使用SQL
Jonathon Day说
“更新不应该是SQL命令的forms”。 我还没有遇到任何不能通过Magento的configuration结构执行的DDL或DML语句。
(在这个问题中,我如何将configuration更改从开发迁移到生产环境? )
我想知道如何以这种方式添加/修改/删除列/索引到/从一个表,但不依赖于SQL? 这甚至有可能吗?
此外,还有哪些其他操作只能在SQL中完成?
您可以在安装脚本中使用这些方法:
- 
使用 Varien_Db_Ddl_Table类创build新表,您可以在其中configuration与$this->getConnection()->createTable($tableObject)结合使用的所有字段,键,关系。例如:/* @var $this Mage_Core_Model_Resource_Setup */ $table = new Varien_Db_Ddl_Table(); $table->setName($this->getTable('module/table')); $table->addColumn('id', Varien_Db_Ddl_Table::TYPE_INT, 10, array('unsigned' => true, 'primary' => true)); $table->addColumn('name', Varien_Db_Ddl_Table::TYPE_VARCHAR, 255); $table->addIndex('name', 'name'); $table->setOption('type', 'InnoDB'); $table->setOption('charset', 'utf8'); $this->getConnection()->createTable($table);
- 
使用安装连接( $this->getConnection())方法:-   addColumn()方法将新列添加到正在退出的表中。 它有这样的参数:-   $tableName– 应该修改的表名
-   $columnName– 应该添加的列的名称
-   $definition– 定义列(INT(10),DECIMAL(12,4)等)
 
-   
-   addConstraint()方法创build一个新的约束外键。 它有这样的参数-   $fkName– 外键名称,每个数据库应该是唯一的,如果你没有指定FK_前缀,它将被自动添加
-   $tableName– 用于添加外键的表名
-   $columnName– 应该被引用到另一个表的列名,如果你有复杂的外键,使用逗号来指定多个列
-   $refTableName– 将被处理的外部表名
-   $refColumnName–$refColumnName的列名
-   $onDelete– 在$onDelete删除行的操作。 可以是空string(什么都不做),cascade,set null。 该字段是可选的,如果没有指定,将使用cascade值。
-  外键表中行密钥更新的$onUpdate操作。 可以是空string(什么都不做),cascade,set null。 该字段是可选的,如果没有指定,将使用cascade值。
-   $purge– 一个标志,用于在外键添加后清除行(例如删除未被引用的logging)
 
-   
-   addKey()方法用于向表中添加索引。 它有这样的参数:-   $tableName– 应该添加索引的表名
-   $indexName– 索引名称
-   $fields– 索引中使用的列名
-   $indexType– 索引的types。 可能的值有:index,unique,primary,fulltext。 此参数是可选的,所以默认值是index
 
-   
-   dropColumn()方法用于从现有表中删除列。 它有这样的参数:-   $tableName– 应该修改的表名
-   $columnName– 应该删除的列的名称
 
-   
-   dropForeignKey()方法用于删除外键。 它有这样的参数:-   $tableName– 用于删除外键的表名
-   $fkName– 外键名称
 
-   
-   dropKey()方法用于删除表索引。 它有这样的参数:-   $tableName– 索引应该被删除的表名
-   $keyName– 索引名称
 
-   
-   modifyColumn方法用于修改表中的现有列。 它有这样的参数:-   $tableName– 应该修改的表名
-   $columnName– 应该重命名的列的名称
-   $definition– 列的新定义(INT(10),DECIMAL(12,4)等)
 
-   
-   changeColumn方法用于修改和重命名表中的现有列。 它有这样的参数:-   $tableName– 应该修改的表名
-   $oldColumnName– 列的旧名称,应该重命名和修改
-   $newColumnName– 列的新名称
-   $definition– 列的新定义(INT(10),DECIMAL(12,4)等)
 
-   
-   changeTableEngine方法用于更改表引擎,例如从MyISAM到InnoDB。 它有这样的参数:-   $tableName– 表名
-   $engine– 新引擎名称(MEMORY,MyISAM,InnoDB等)
 
-   
 
-   
 你也可以使用tableColumnExists方法来检查列的存在。 
 这不是完整的可用的方法列表,以摆脱直接的SQL查询写作。 你可以在Varien_Db_Adapter_Pdo_Mysql和Zend_Db_Adapter_Abstract类find更多。 
不要犹豫,看看你将要使用的类定义,你可以find很多有趣的事情:)
任何Magento更新不应该包括SQL的想法是基于这个想法
- 
Magento对象在数据库/数据存储层之上提供抽象 
- 
你应该使用抽象来更新Magento,它确保Magento团队如何改变对象与数据存储的交互方式,你的更新仍然有效(假设核心团队维护Object方法所隐含的原始“契约”) 
 所以,问题是一个ALTER TABLE语句直接改变数据存储。 如果您仅仅订阅上述两个想法,则不应该更改数据存储。  (在添加列或索引的情况下意味着仅使用EAV模型,使用设置资源来pipe理更改以及接受Magento的索引)。 
一个很好的经验法则是,如果你正在改变或增加一些核心的Magentofunction(产品,评论等),远离直接改变数据库结构,除非你愿意在升级过程中仔细pipe理它。
如果您正在构build新的对象和function,则使用您要创build的任何SQL,并通过“设置资源”更改您的表。 如果你看安装程序/升级文件,你可以看到核心的Magento团队自己做这个。
要改变表格并用外键添加列,我已经成功地使用了Magento CE v1.6.1.0:
 // Alter table to add column $installer->getConnection() ->addColumn( $installer->getTable('modulekey/model'), 'column_name', array( 'type' => Varien_Db_Ddl_Table::TYPE_INTEGER, 'length' => null, 'unsigned' => true, 'nullable' => true, 'comment' => 'Foreign key' ) ); // Add foreign key constraint $installer->getConnection() ->addForeignKey( $installer->getFkName( 'modulekey/model', 'column_name', 'modulekey/foreign_model', 'foreign_column_name' ), $installer->getTable('modulekey/model'), 'column_name', $installer->getTable('modulekey/foreign_model'), 'foreign_column_name', Varien_Db_Ddl_Table::ACTION_SET_NULL, Varien_Db_Ddl_Table::ACTION_SET_NULL ); 
 这些是来自Varien_Db_Adapter_Pdo_Mysql方法。