在 Magento 设置脚本中更改表而不使用 SQL

乔纳森·戴

“更新不应采用 SQL 命令的形式”。我没有遇到任何无法通过Magento的配置结构执行的DDL或DML语句。

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

我想知道如何最好地以这种方式向/修改/删除表/删除列或索引,但不依赖于SQL?这有可能吗?

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


答案 1

您可以在安装脚本中使用以下方法:

  • 使用 class 创建新表,您可以在其中配置所有字段、键、关系,并结合示例: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 nullcascade
      • $onUpdate在外表中更新行键时执行操作。可以是空字符串(不执行任何操作),、 。此字段是可选的,如果未指定,则将使用值。cascadeset nullcascade
      • $purge- 用于在添加外键后启用行清理的标志(例如,删除未引用的记录)
    • addKey()方法用于向表中添加索引。它具有这样的参数:
      • $tableName- 应添加索引的表名
      • $indexName- 索引名称
      • $fields- 索引中使用的列名
      • $indexType- 索引的类型。可能的值为:、 、 、 。此参数是可选的,因此默认值为indexuniqueprimaryfulltextindex
    • 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

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


答案 2

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

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

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

因此,问题是语句直接更改数据存储。如果您只订阅上述两个想法,则永远不应该更改数据存储。(在添加列或索引的情况下,这意味着仅使用EAV模型,使用设置资源来管理更改,并接受Magento的索引)。ALTER TABLE

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

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


推荐