Comme vu dans un précédent billet (MySQL et les modèles Django), il existe des inconsistances entre une base de donnée MySQL et sa représentation par des modèles Django.
Création des tables à partir des modèles Django
Lorsqu'on utilise python manage.py syncdb, les tables créées dans la base de données
- N'auront aucun commentaire, que ce soit sur les champs ou les tables, qu'il y ai ou non des help_text et des docstrings
- N'auront aucun champ *ENUM*: les champs possédant une liste de choix sont représentés par un *VARCHAR* de longueur égale à la taille du plus long des choix
- Les valeurs par défaut indiquées dans les modèles ne sont pas transmises dans les scripts de création des tables
- Les *BooleanField* sont représentés par des TINYINT de 1bit
- Un DateTimeField avec le paramètre auto_add_now ne sera pas représenté par un TIMESTAMP avec la valeur par défaut CURRENT_TIMESTAMP
Inspection des tables dans Django
Par ailleurs, si la base de donnée existe déjà, et que les modèles sont créés automatiquement par l'utilisation de la commande python manage.py inspectdb, il faudra garder à l'esprit que:
- Les commentaires sur les champs et tables ne sont pas traduits en help_text ou docstrings, il faudra donc les dupliquer manuellement
- Un champ ENUM sera représenté par un CharField
- Les tailles de champ ne sont pas respectées. Par exemple, un Charfield sera avec un max_length de 135 par défaut
- Les champs TIMESTAMP avec une valeur par défaut de CURRENT_TIMESTAMP ne seront pas importés en champ avec une valeur par défaut auto_add_now
- Les valeurs par défaut ne sont pas importées
Il y a deux derniers points à noter:
- Le script d'inspection va importer les champs primary_key pour chaque table, alors qu'ils peuvent être automatiquement générés de manière transparente: un modèle sans primary_key explicite en aura un de manière implicite
- Le script d'inspection va créer un modèle pour les tables utilisées pour les relations ManyToMany alors que là aussi, Django peut les générer de manière implicite dans la plupart des cas (lorsque cette table ne contient pas d'information supplémentaire)
Je trouve préférable de laisser la gestion implicite des primary_key et des tables ManyToMany quand c'est possible, dans un soucis de concision et de lisibilité.
Néanmoins, celà introduit une inconsistance entre les modèles et leur représentation dans la base de donnée, inconsistance qui peut porter à confusion.
Plus de cohérence entre les modèles et la base de donnée
Plusieurs possibilités:
- créer un script python qui va introspecter les modèles, et automatiquement rajouter les help_text comme commentaires aux champs, et les docstrings comme commentaires aux tables, ou vice-versa
- Utiliser des *Custom SQL*
- Créer des *Custom fields*
- Pour le type ENUM, il existe un *django snippet* qui vise à apporter une meilleure cohérence dans son utilisation
Partagez vos astuces et faites part d'autres incohérences dans les commentaires!