不使用SQL的Magento安装脚本中的ALTER TABLE

时间:2010-11-30 15:54:46

标签: php sql magento installation entity-attribute-value

Jonathon Day

  

“更新不应该是以。的形式   SQL命令“。我没有遇到过   任何不能的DDL或DML语句   通过Magento的配置执行   结构。

(问题How can I migrate configuration changes from development to production environment?

我想知道如何以这种方式向表中添加/修改/删除列或索引,但不依赖于SQL?它甚至可能吗?

此外,还有哪些其他操作只能在SQL中完成?

3 个答案:

答案 0 :(得分:128)

您可以在设置脚本中使用此类方法:

  • 使用Varien_Db_Ddl_Table类创建新表,您可以在其中配置所有字段,键,关系以及$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()方法创建一个新的约束外键。它有这样的参数
      • $fkName - 外键名称,每个数据库应该是唯一的,如果您没有指定FK_前缀,它将自动添加
      • $tableName - 添加外键的表名
      • $columnName - 应该引用另一个表的列名,如果您有复杂的外键,请使用逗号指定多个列
      • $refTableName - 将处理的外部表名
      • $refColumnName - 外表中的列名
      • $onDelete - 对外表中的行删除操作。可以是空字符串(不执行任何操作),cascadeset null。此字段是可选字段,如果未指定,则将使用cascade值。
      • $onUpdate对外表中行键更新的操作。可以是空字符串(不执行任何操作),cascadeset null。此字段是可选字段,如果未指定,则将使用cascade值。
      • $purge - 在外键添加后启用清除行的标志(例如,删除未引用的记录)
    • addKey()方法用于向表中添加索引。它有这样的参数:
      • $tableName - 应添加索引的表名
      • $indexName - 索引名称
      • $fields - 索引中使用的列名称
      • $indexType - 索引的类型。可能的值包括: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课程中找到更多内容。

不要犹豫,查看你将要使用的课程定义,你可以为自己找到很多有趣的东西:)

答案 1 :(得分:18)

任何Magento更新都不应该包含SQL的想法是基于

的想法
  1. Magento Objects在您的数据库/数据存储层之上提供抽象

  2. 您应该使用抽象来更新Magento,这可以确保Magento团队如果更改对象与数据存储区的交互方式,您的更新仍然有效(假设核心团队维护对象隐含的原始“合同”)方法)

  3. 因此,问题是ALTER TABLE语句直接更改数据存储区。如果您只完全赞同上述两个想法,那么您永远不应该更改数据存储。 (在添加列或索引的情况下,仅指使用EAV模型,使用设置资源来管理更改,并接受Magento的索引)。

    一个好的一般经验法则是,如果您正在更改或添加某些核心Magento功能(产品,评论等),请远离直接更改数据库结构,除非您愿意在此期间仔细管理它升级。

    如果要构建新对象和功能,请使用您要创建的任何SQL,并通过“设置资源”更改表。如果您查看安装程序/升级文件,您可以看到核心Magento团队自己完成此任务。

答案 2 :(得分:12)

要改变表并使用外键添加列,我已成功使用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的方法。