Bugs/limitations des Migrations avec MySQL (ou d'autres SGBD

Bonjour,

Je suis en train de travailler sur mon premier projet Rails, et je suis
déjà agacé par des bugs ou limitations des migrations que je rencontre
avec MySQL. Je voulais savoir si vous rencontrez aussi ces soucis, et
s’il y a une solution élégante. Je suis en Rails 1.2.3, tous les paquets
sont en Gems, sur Ubuntu 7.04.

  1) Problème avec add_column :

Il n’est pas possible de préciser après quelle colonne existante ajouter
la nouvelle colonne. La migration ajoute toujours la nouvelle colonne en
dernier.

MySQL sait le faire, mais je ne sais pas si c’est une extension au SQL
ou pas. J’ai regardé le code source dans Active Record et il n’y a aucun
moyen d’ajouter de paramètres à part ceux déjà définis.
J’ai contourné mon problème comme ceci, mais ça ne me semble pas élégant
:

class AddOrRenameFields < ActiveRecord::Migration
  def self.up
    # Champ 'name' manquant. On veut qu'elle soit ajoutée après le
champ 'sim'
    # Cette commande ne convient pas : add_column :containers,
:name, :string, :limit => 64, :null => false
    say_with_time("Adding column 'name' to 'containers'") do
      execute "ALTER TABLE containers ADD COLUMN `name` VARCHAR(64)
NOT NULL AFTER `sim`"
    end
[...]
end

Quelqu’un a-t-il mieux ? J’ai l’impression qui faudrait modifier la
méthode :

      def add_column_options!(sql, options) #:nodoc:
        sql << " DEFAULT #{quote(options[:default],
options[:column])}" if options_include_default?(options)
        sql << " NOT NULL" if options[:null] == false
      end

dans
/activerecord-1.15.3/lib/active_record/connection_adapters/abstract/schema_statements.rb/
pour ajouter le support de “FIRST” ou “AFTER nom_de_colonne”.

  2) Problème avec rename_column :

Avec MySQL, quand je renomme une colonne, je perds tous les attributs !
Par exemple “NOT NULL” disparaît.

La faute en revient à ce bout de code dans
/activerecord-1.15.3/lib/active_record/connection_adapters/mysql_adapter.rb/,
qui ne passe pas tous les paramètres possibles à “ALTER TABLE … CHANGE
…” :

      def rename_column(table_name, column_name, new_column_name)
#:nodoc:
        current_type = select_one("SHOW COLUMNS FROM #{table_name}
LIKE '#{column_name}'")["Type"]
        execute "ALTER TABLE #{table_name} CHANGE #{column_name}
#{new_column_name} #{current_type}"
      end

“SHOW COLUMNS” retourne toutes les infos qu’il faut pour reconstituer
“NULL” et la valeur par défaut, mais AR ne s’en sert pas. Donc j’ai dû
utiliser le code suivant :

class AddOrRenameFields < ActiveRecord::Migration
  def self.up
[...]
    # Le champ 'type' est réservé par Rails
    # Attention, Rails perd les attributs d'une colonne renommée !!!
On doit les remettre à la main.
    rename_column :objects_in_world, :type, :otype
    change_column :objects_in_world, :otype, :string, :limit => 16,
:null => false
    rename_column :objects_off_world, :type, :otype
    change_column :objects_off_world, :otype, :string, :limit => 16,
:null => false
  end
end

De même, quelqu’un a-t-il une solution élégante à proposer ?

Ou bien faut-il que je fasse des patchs ou bug reports ?

Cordialement,


Farzad FARID / Architecte Open Source - Associé
Pragmatic Source / http://www.pragmatic-source.com
Tel : +33 9 53 19 21 90 / Mob : +33 6 03 70 65 46
Rejoignez mon réseau de contacts :
http://www.viadeo.com/invitationpersonnelle/002ic6twokcvmi

D’une manière générale, il est assez facile de faire du monkey
patching (*) pour Rails (merci Ruby). S’il n’existe pas déjà un gem,
une lib ou un plugin qui règle tes problèmes, tu peux donc facilement
écrire le code qui va bien pour régler tes petits soucis (puisque tu
as déjà identifier les endroits problématiques dans le code de Rails).

(*) Monkey patch - Wikipedia

Le 14/08/07, Farzad FARID[email protected] a écrit :

On 8/14/07, Farzad FARID [email protected] wrote:

Bonjour,

  1. Problème avec add_column : Il n’est pas possible de préciser après quelle
    colonne existante ajouter la nouvelle colonne. La migration ajoute toujours
    la nouvelle colonne en dernier.

Je vais poser la question naïvement : est-ce que c’est si grave que ça ?


Nicolas D.
N’imprimez ce mail que si vous ne savez pas le lire sur l’écran : les
électrons se recyclent bien, le papier, beaucoup moins bien.

On 8/14/07, Nicolas D. [email protected] wrote:

Je vais poser la question naïvement : est-ce que c’est si grave que ça ?
J’enfonce même le clou, à quoi ça sert ?

A priori ça ne change rien à l’optimisation des performances. Et
théoriquement tu devrais toujours utiliser les noms de colonne ou des
alias donc ça ne changera rien non plus à tes requêtes SQL.


Éric Daspet
http://eric.daspet.name/

Le 14/08/07, Farzad FARID[email protected] a écrit :

Bonjour,

  1. Problème avec add_column : Il n’est pas possible de préciser après quelle
    colonne existante ajouter la nouvelle colonne. La migration ajoute toujours
    la nouvelle colonne en dernier.

Bonjour.

Je rejoint les posts déjà emis sur le fait que ça na aucune
importance, à part esthétique, et encore…

Par contre ton deuxième point est plus interessant, et plus important
à mes yeux.

En gros il faut respécifier les attributs de colonne lors d’une
migration ? (Enfin d’un rennomage de colonne si j’ai bien suivi).
C’est presque dommage, mais pas si grave non plus. Non ?


Yannick “Pouype” Francois
http://www.typouype.org
http://www.rubyfrance.org

Nicolas D. a écrit :

On 8/14/07, Farzad FARID [email protected] wrote:

Bonjour,

  1. Problème avec add_column : Il n’est pas possible de préciser après quelle
    colonne existante ajouter la nouvelle colonne. La migration ajoute toujours
    la nouvelle colonne en dernier.

Je vais poser la question naïvement : est-ce que c’est si grave que ça ?

Tu as raison de poser la question. Dans mon cas non ce n’est pas grave,
c’est surtout esthétique, et c’est aussi parce que je suis un peu
perfectionniste :slight_smile:

Mais, dans l’absolu, je crois que quand on fait de l’administration de
base de données de haut niveau, notamment avec Oracle, l’ordre des
colonnes dans une tables peut avoir une influence sur les performances,
l’indexation, le stockage sur disque, etc. Donc la question peut se
poser à ce moment là . Là tu pourrais me répondre à juste titre qu’à ce
niveau d’expertise on ne s’amuse plus à utiliser les migrations…

Néanmoins, la possibilité de choisir l’emplacement est là , au moins
dans MySQL, et il est dommage de ne pas pouvoir l’exploiter dans Rails
car je pense que ça peut s’écrire en moins de 10 lignes. Je ferai
peut-être un patch ou monkey-patch quand j’aurai le temps.


Farzad FARID / Architecte Open Source - Associé
Pragmatic Source / http://www.pragmatic-source.com
Tel : +33 9 53 19 21 90 / Mob : +33 6 03 70 65 46
Rejoignez mon réseau de contacts :
http://www.viadeo.com/invitationpersonnelle/002ic6twokcvmi

Bonjour,

Yannick F. a écrit :

Par contre ton deuxième point est plus interessant, et plus important
à mes yeux.

En gros il faut respécifier les attributs de colonne lors d’une
migration ? (Enfin d’un rennomage de colonne si j’ai bien suivi).
C’est presque dommage, mais pas si grave non plus. Non ?

Je trouve que ça l’est quand ce n’est pas documenté et que ton modèle
peut se trouver “dégradé” à ton insu. Pour info PhpMyAdmin renomme les
colonnes MySQL correctement :slight_smile: D’autre part, re-spécifier les attributs
dans la nouvelle migration ce n’est pas vraiment DRY il me semble.

C’est pourquoi je pense que le 2ème point peut être qualifié de bug.

Cordialement,


Farzad FARID / Architecte Open Source - Associé
Pragmatic Source / http://www.pragmatic-source.com
Tel : +33 9 53 19 21 90 / Mob : +33 6 03 70 65 46
Rejoignez mon réseau de contacts :
http://www.viadeo.com/invitationpersonnelle/002ic6twokcvmi

On 8/15/07, Farzad FARID [email protected] wrote:

C’est presque dommage, mais pas si grave non plus. Non ?

Je trouve que ça l’est quand ce n’est pas documenté et que ton modèle
peut se trouver “dégradé” à ton insu. Pour info PhpMyAdmin renomme les
colonnes MySQL correctement :slight_smile: D’autre part, re-spécifier les attributs
dans la nouvelle migration ce n’est pas vraiment DRY il me semble.

PhPMyadmin le fait peut-être mais pas MySQL. Donc après tout c’est
logique aussi.

As-tu essayé avec les autre SGBD ? Car ca peux peut-être n’être qu’une
limitation dû à MySQL et donc il faut mettre à jour l’adaptater
uniquement.


Cyril M.

Farzad a écrit :

C’est pourquoi je pense que le 2ème point peut être qualifié de bug.
Tout à fait, c’en est un.

2 tickets à ce sujet :

http://dev.rubyonrails.org/ticket/6999
http://dev.rubyonrails.org/ticket/7142

-- Jean-François.


Ruby ( http://www.rubyfrance.org ) on Rails ( http://www.railsfrance.org
)