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(什么都不做), cascadeset null 。 该字段是可选的,如果没有指定,将使用cascade值。
      • 外键表中行密钥更新的$onUpdate操作。 可以是空string(什么都不做), cascadeset null 。 该字段是可选的,如果没有指定,将使用cascade值。
      • $purge – 一个标志,用于在外键添加后清除行(例如删除未被引用的logging)
    • addKey()方法用于向表中添加索引。 它有这样的参数:
      • $tableName – 应该添加索引的表名
      • $indexName – 索引名称
      • $fields – 索引中使用的列名
      • $indexType – 索引的types。 可能的值有: indexuniqueprimaryfulltext 。 此参数是可选的,所以默认值是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 – 新引擎名称( MEMORYMyISAMInnoDB等)

你也可以使用tableColumnExists方法来检查列的存在。

这不是完整的可用的方法列表,以摆脱直接的SQL查询写作。 你可以在Varien_Db_Adapter_Pdo_MysqlZend_Db_Adapter_Abstract类find更多。

不要犹豫,看看你将要使用的类定义,你可以find很多有趣的事情:)

任何Magento更新不应该包括SQL的想法是基于这个想法

  1. Magento对象在数据库/数据存储层之上提供抽象

  2. 你应该使用抽象来更新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方法。