web-dev-qa-db-fra.com

ALTER TABLE dans le script d'installation de Magento sans utiliser SQL

Jonathon Day dit

"les mises à jour NE DEVRAIENT PAS être sous la forme de commandes SQL". Je n'ai rencontré aucune déclaration DDL ou DML qui ne peut pas être exécutée via les structures de configuration de Magento.

(Dans la question Comment puis-je migrer les modifications de configuration du développement vers l'environnement de production? )

Je voudrais savoir comment ajouter/modifier/supprimer au mieux une colonne ou un index à/d'une table de cette manière, mais sans compter sur SQL? Est-ce même possible?

De plus, quelles autres actions ne peuvent être effectuées qu'en SQL?

54
clockworkgeek

Vous pouvez utiliser ces méthodes dans votre script d'installation:

  • Utilisez la classe Varien_Db_Ddl_Table Pour créer de nouvelles tables, où vous pouvez configurer tous les champs, clés et relations en combinaison avec $this->getConnection()->createTable($tableObject) Exemple:

    /* @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);
    
  • Utilisez les méthodes de connexion de configuration ($this->getConnection()):

    • La méthode addColumn() ajoute une nouvelle colonne à la table en cours de sortie. Il a de tels paramètres:
      • $tableName - le nom de la table à modifier
      • $columnName - le nom de la colonne à ajouter
      • $definition - définition de la colonne (INT(10), DECIMAL(12,4), etc.)
    • La méthode addConstraint() crée une nouvelle clé étrangère de contrainte. Il a de tels paramètres
      • $fkName - le nom de la clé étrangère doit être unique par base de données, si vous ne spécifiez pas le préfixe FK_, Il sera ajouté automatiquement
      • $tableName - le nom de la table pour ajouter une clé étrangère
      • $columnName - le nom de la colonne qui doit être référé à une autre table, si vous avez une clé étrangère complexe, utilisez une virgule pour spécifier plus d'une colonne
      • $refTableName - le nom de la table étrangère, qui sera gérée
      • $refColumnName - le (s) nom (s) de colonne dans la table étrangère
      • $onDelete - action sur la suppression de ligne dans la table étrangère. Peut être une chaîne vide (ne rien faire), cascade, set null. Ce champ est facultatif et s'il n'est pas spécifié, la valeur cascade sera utilisée.
      • $onUpdate Action sur la mise à jour de la clé de ligne dans la table étrangère. Peut être une chaîne vide (ne rien faire), cascade, set null. Ce champ est facultatif et s'il n'est pas spécifié, la valeur cascade sera utilisée.
      • $purge - un indicateur pour permettre le nettoyage des lignes après l'ajout d'une clé étrangère (par exemple, supprimer les enregistrements qui ne sont pas référencés)
    • La méthode addKey() est utilisée pour ajouter des index à une table. Il a de tels paramètres:
      • $tableName - le nom de la table où l'index doit être ajouté
      • $indexName - le nom de l'index
      • $fields - nom (s) de colonne utilisé (s) dans l'index
      • $indexType - type de l'index. Les valeurs possibles sont: index, unique, primary, fulltext. Ce paramètre est facultatif, donc la valeur par défaut est index
    • La méthode dropColumn() est utilisée pour supprimer des colonnes de la table existante. Il a de tels paramètres:
      • $tableName - le nom de la table à modifier
      • $columnName - le nom de la colonne à supprimer
    • dropForeignKey() La méthode est utilisée pour supprimer les clés étrangères. Il a de tels paramètres:
      • $tableName - le nom de la table pour supprimer une clé étrangère
      • $fkName - le nom de la clé étrangère
    • La méthode dropKey() est utilisée pour supprimer les index de table. Il a de tels paramètres:
      • $tableName - le nom de la table où l'index doit être supprimé
      • $keyName - le nom de l'index
    • La méthode modifyColumn est utilisée pour modifier la colonne existante dans la table. Il a de tels paramètres:
      • $tableName - le nom de la table à modifier
      • $columnName - le nom de la colonne, qui doit être renommée
      • $definition - une nouvelle définition de la colonne (INT(10), DECIMAL(12,4), etc.)
    • La méthode changeColumn est utilisée pour modifier et renommer la colonne existante dans la table. Il a de tels paramètres:
      • $tableName - le nom de la table à modifier
      • $oldColumnName - l'ancien nom de la colonne, qui devrait être renommé et modifié
      • $newColumnName - un nouveau nom de la colonne
      • $definition - une nouvelle définition de la colonne (INT(10), DECIMAL(12,4), etc.)
    • La méthode changeTableEngine est utilisée pour changer le moteur de table, de MyISAM à InnoDB par exemple. Il a de tels paramètres:
      • $tableName - le nom de la table
      • $engine - nouveau nom du moteur (MEMORY, MyISAM, InnoDB, etc.)

Vous pouvez également utiliser la méthode tableColumnExists pour vérifier l'existence de la colonne.

Ce n'est pas la liste complète des méthodes disponibles pour vous débarrasser de l'écriture directe des requêtes SQL. Vous pouvez en trouver plus dans les classes Varien_Db_Adapter_Pdo_Mysql Et Zend_Db_Adapter_Abstract.

N'hésitez pas à regarder la définition de classe que vous allez utiliser, vous pouvez trouver plein de choses intéressantes :)

128
Ivan Chepurnyi

L'idée que toute mise à jour de Magento NE DEVRAIT PAS inclure SQL est basée sur l'idée que

  1. Les objets Magento fournissent des abstractions au-dessus de votre couche de base de données/magasin de données

  2. Vous devez utiliser les abstractions pour mettre à jour Magento, ce qui garantit que si l'équipe Magento change la façon dont les objets interagissent avec la banque de données, vos mises à jour continueront de fonctionner (en supposant que l'équipe principale conserve les "contrats" d'origine impliqués par les méthodes Object)

Donc, le problème est un ALTER TABLE instruction change directement la banque de données. Si vous vous abonnez exclusivement aux deux idées ci-dessus, vous ne devez jamais modifier le magasin de données. (ce qui, dans le cas de l'ajout d'une colonne ou d'un index, signifie utiliser exclusivement des modèles EAV, utiliser les ressources de configuration pour gérer les modifications et accepter l'indexation de Magento).

Une bonne règle générale est que, si vous modifiez ou ajoutez des fonctionnalités de base de Magento (produits, avis, etc.), évitez de modifier directement la structure de la base de données, sauf si vous êtes prêt à la gérer soigneusement pendant les mises à niveau.

Si vous créez de nouveaux objets et fonctionnalités, utilisez le SQL que vous souhaitez créer et modifier vos tables via les ressources de configuration. Si vous regardez les fichiers d'installation/mise à niveau, vous pouvez voir que l'équipe principale de Magento le fait elle-même.

18
Alan Storm

Pour modifier la table et ajouter une colonne avec une clé étrangère, je l'ai utilisé avec succès en utilisant 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
        );

Ce sont des méthodes de Varien_Db_Adapter_Pdo_Mysql.

12
Bouni