“更新不应该是以。的形式 SQL命令“。我没有遇到过 任何不能的DDL或DML语句 通过Magento的配置执行 结构。
(问题How can I migrate configuration changes from development to production environment?)
我想知道如何以这种方式向表中添加/修改/删除列或索引,但不依赖于SQL?它甚至可能吗?
此外,还有哪些其他操作只能在SQL中完成?
答案 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
- 对外表中的行删除操作。可以是空字符串(不执行任何操作),cascade
,set null
。此字段是可选字段,如果未指定,则将使用cascade
值。 $onUpdate
对外表中行键更新的操作。可以是空字符串(不执行任何操作),cascade
,set null
。此字段是可选字段,如果未指定,则将使用cascade
值。 $purge
- 在外键添加后启用清除行的标志(例如,删除未引用的记录)addKey()
方法用于向表中添加索引。它有这样的参数:
$tableName
- 应添加索引的表名$indexName
- 索引名称$fields
- 索引中使用的列名称$indexType
- 索引的类型。可能的值包括: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
课程中找到更多内容。
不要犹豫,查看你将要使用的课程定义,你可以为自己找到很多有趣的东西:)
答案 1 :(得分:18)
任何Magento更新都不应该包含SQL的想法是基于
的想法Magento Objects在您的数据库/数据存储层之上提供抽象
您应该使用抽象来更新Magento,这可以确保Magento团队如果更改对象与数据存储区的交互方式,您的更新仍然有效(假设核心团队维护对象隐含的原始“合同”)方法)
因此,问题是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
的方法。