ALTER TABLE в скрипте установки Magento без использования SQL - PullRequest
54 голосов
/ 30 ноября 2010

Джонатон Дэй говорит

"обновления НЕ ДОЛЖНЫ быть в форме команд SQL".Я не сталкивался ни с какими DDL или DML-отчетами, которые не могут быть выполнены через структуры конфигурации Magento.

(В вопросе Как я могу перенести изменения конфигурации из разработки в производственную среду? )

Я хотел бы знать, как лучше всего добавить / изменить / удалить столбец или индекс в / из таблицы таким способом, но не полагаясь на SQL?Возможно ли это вообще?

Кроме того, какие еще действия можно выполнять только в SQL?

Ответы [ 3 ]

128 голосов
/ 30 ноября 2010

Вы можете использовать такие методы в вашем скрипте установки:

  • Используйте класс 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 классах.

Не стесняйтесь заглянуть в определение класса, которое вы собираетесь использовать, вы можете найти для себя много интересного:)

18 голосов
/ 30 ноября 2010

Идея, что любые обновления Magento НЕ ДОЛЖНЫ включать SQL, основана на идее, что

  1. Объекты Magento предоставляют абстракции поверх слоя базы данных / хранилища данных

  2. Вы должны использовать абстракции для обновления Magento, что гарантирует, что если команда Magento изменит взаимодействие объектов с хранилищем данных, ваши обновления будут работать (при условии, что основная команда поддерживает первоначальные «контракты», подразумеваемые объектом). методы)

Итак, проблема в том, что оператор ALTER TABLE напрямую изменяет хранилище данных. Если вы подписываетесь исключительно на две вышеупомянутые идеи, вам никогда не следует менять хранилище данных. (что в случае добавления столбца или индекса означает использование исключительно моделей EAV, использование ресурсов установки для управления изменениями и принятие индексации Magento).

Хорошее общее практическое правило: если вы изменяете или добавляете некоторые основные функции Magento (продукты, обзоры и т. Д.), Избегайте прямого изменения структуры базы данных, если вы не готовы тщательно управлять ею во время обновления.

Если вы создаете новые объекты и функциональные возможности, используйте любой SQL, который вы хотите создать, и изменяйте свои таблицы через установочные ресурсы. Если вы посмотрите на файлы установщика / обновления, вы увидите, что основная команда Magento делает это самостоятельно.

12 голосов
/ 21 августа 2013

Чтобы изменить таблицу и добавить столбец с внешним ключом, я успешно использовал это, используя 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.

...