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

clo*_*eek 54 php sql installation magento entity-attribute-value

乔纳森日

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

(在问题中如何将配置更改从开发迁移到生产环境?)

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

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

Iva*_*nyi 128

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

  • 使用Varien_Db_Ddl_Tableclass创建新表,您可以在其中配置所有字段,键,关系以及$this->getConnection()->createTable($tableObject) Example:

    /* @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);
    
    Run Code Online (Sandbox Code Playgroud)
  • 使用setup connection($this->getConnection())方法:

    • addColumn()方法将新列添加到退出表.它有这样的参数:
      • $tableName - 应修改的表名
      • $columnName- 应添加的列名称
      • $definition-列的定义(INT(10),DECIMAL(12,4)等)
    • addConstraint()method创建一个新的约束外键.它有这样的参数
      • $fkName- 外键名称,每个数据库应该是唯一的,如果不指定FK_前缀,则会自动添加
      • $tableName - 用于添加外键的表名
      • $columnName - 应该引用另一个表的列名,如果您有复杂的外键,请使用逗号指定多个列
      • $refTableName - 将处理的外部表名
      • $refColumnName - 外表中的列名
      • $onDelete - 对外表中的行删除操作.可以为空字符串(什么都不做)cascade,set null.此字段是可选的,如果未指定,cascade则将使用值.
      • $onUpdate对外表中行键更新的操作.可以为空字符串(什么都不做)cascade,set null.此字段是可选的,如果未指定,cascade则将使用值.
      • $purge - 用于在外键添加后启用行清除的标志(例如,删除未引用的记录)
    • addKey()method用于向表中添加索引.它有这样的参数:
      • $tableName - 应添加索引的表名
      • $indexName - 索引名称
      • $fields - 索引中使用的列名称
      • $indexType - 索引的类型.可能的值有:index,unique,primary,fulltext.此参数是可选的,因此默认值为index
    • dropColumn()method用于从现有表中删除列.它有这样的参数:
      • $tableName - 应修改的表名
      • $columnName- 应删除的列名称
    • dropForeignKey()方法用于删除外键.它有这样的参数:
      • $tableName - 用于删除外键的表名
      • $fkName - 外键名称
    • dropKey()method用于删除表索引.它有这样的参数:
      • $tableName - 应删除索引的表名
      • $keyName - 索引名称
    • modifyColumnmethod用于修改表中的现有列.它有这样的参数:
      • $tableName - 应修改的表名
      • $columnName- 应重命名的列的名称
      • $definition-列的新的定义(INT(10),DECIMAL(12,4)等)
    • changeColumnmethod用于修改和重命名表中的现有列.它有这样的参数:
      • $tableName - 应修改的表名
      • $oldColumnName- 列的旧名称,应重命名和修改
      • $newColumnName- 列的新名称
      • $definition-列的新的定义(INT(10),DECIMAL(12,4)等)
    • changeTableEngine方法用于更改表引擎,例如从MyISAM到InnoDB.它有这样的参数:
      • $tableName - 表名
      • $engine-新的引擎名称(MEMORY,MyISAM,InnoDB等)

您也可以使用tableColumnExists方法来检查列的存在.

它不是可用于解决直接SQL查询编写的完整方法列表.你可以找到更多的Varien_Db_Adapter_Pdo_MysqlZend_Db_Adapter_Abstract类.

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

  • 很高兴知道那些在那里! (2认同)
  • 谢谢伊万.这是一个很棒的方法参考!我看过Mage_*课程,没有看到这样的东西,所以开始绝望了.希望我的更新脚本将来会更整洁. (2认同)
  • @clockworkgeek欢迎.顺便说一句,Mage只包含Magento的MVC实现,用于处理FileSystem,DB,Sockets的API,不同的文件格式放在lib/Varien下,很多类都是从Zend Framework扩展而来的 (2认同)
  • @Jonathan希望Magento 2.0对开发人员更友好,特别是在数据库升级方面.但当然它只会扩展Zend_Db.使用Doctrine 2.0 orm可以解决这个问题,但需要从头开始重写Magento :) (2认同)
  • @demonkoryu我没有在1.3中看到它并且在1.4中看到它. (2认同)

Ala*_*orm 18

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

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

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

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

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

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

  • 我非常喜欢你在知识库中的文章:)但并不是所有magento(关键和最常用)对象都不能用EAV进行扩展,因为它们是平面表结构(如顺序和引用)并向需要使用的那些添加变量即使你通过提供的方法这样做,也可以改变表格.回滚这种变化需要在数据完整性和管理方面采取额外措施. (4认同)
  • 顺便说一下,@ Anton,订单和引号在设置脚本中都有伪EAV API.例如,为订单实体调用`addAttribute`方法将导致在`order_flat`表中创建一个新列. (3认同)
  • @Anton模块安装类应该从`Mage_Sales_Model_Mysql4_Setup`扩展为此功能 (2认同)

Bou*_*uni 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
        );
Run Code Online (Sandbox Code Playgroud)

那些是来自的方法Varien_Db_Adapter_Pdo_Mysql.