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
方法。