Archive

Archives pour 03/2009

Le contrôle de versions de sources: pourquoi?

30/03/2009 admin 2 commentaires

Je vais vous raconter l’histoire de Brian. Brian est ingénieur informaticien.

Le crash disque

Brian n’a pas de chance, et il a failli devoir pointer à l’ANPE quand il s’est rendu compte que

  1. Son disque dur avait crashé
  2. Il n’avait pas fait de sauvegarde de son boulot

Heureusement, il a pu récuperer les sources sur le serveur de production, et en moins de deux semaines il a pu réimplémenter les dernières fonctionnalités et corrections de bugs qu’il avait apportées au logiciel.

Le boss indécis

Brian n’a vraiment pas de chance, il a un boss indécis qui vient de lui dire qu’il ne voulait finalement plus de la dernière fonctionnalité en date:

« c’est une très mauvaise idée, commercialement parlant, supprime là au plus vite ».

Trois jours plus tard, Brian pense n’avoir oublié d’annuler les modifications dans aucun fichier.

La faute à Murphy

Brian, qui a la poisse, se retrouve à débuguer un morceau de code obscur, et se demande tout à coup qui a bien pu créer ce « code spaghetti ».

  • Serait-ce John, le cousin de l’oncle de sa soeur, qui code comme sa grand-mère?
  • Ou encore Steven, le surfer blond, qui sort juste de l’école et n’a jamais appris à commenter son code?

Si seulement Brian le savait, il pourrait demander des éclaircissement à l’auteur, et aurait quelqu’un à pointer du doigt à son boss qui vient de sortir son fouet.

Le CPOLD: la fausse solution

Pour reprendre le blog de Roland, le CPOLD à d’innombrables qualités:

  • pas de format de fichier complexe et susceptible de corruption
  • pas de conflits
  • aucun besoin d’un serveur dédié (on peut tout mettre ensemble, prod et dev confondues)
  • aucune limitation sur la gestion des branches
  • une rapidité insurpassable
  • une simplicité de mise en oeuvre et d’apprentissage enfantine
  • pas de modèle de développement imposé (centralisé, distribué, en quinconce, en hélice, toutes les variantes sont possibles)
  • des sauvegardes facilitées
  • etc…

Voici en quoi consiste la mise en place du CPOLD:

    $ cp fichier.py fichier.py.old

Et voici un exemple de mise en oeuvre du CPOLD:

    foo_dev
        foo.py
        foo.py.old
        foo.py.old.2009_03_29
        foo.py.marche_pas
        foo.py.todelete
        foo.py.OLD.2006_05_12
        foo.py.bak
        foo.py.fonctionalite_bar
        foo.py.bug
        foo.py.save.20081210
        foo.py.check
        foo.py.test

    foo_prod
        foo.py

    foo_savedev.tgz
    foo_save20090329_v2_0.tgz
    foo_save20080412_v1_2.tgz
    foo_save20060509_v1_0.tgz

Et pour faire bien, voici un extrait du fichier foo.py:

    ...
    def bar(thing): # Added the 10th of june, 2006 -- Steven
        """This function is very usefull!"""
        # Brian: refactored 20080410 for release 1.2
        #if thing == "bar": ### Steven: 11/06/06 fixed typo (was thing = "bar")
        #    return True;
        return (thing == "bar")
    ...

La fausse bonne idée

Nous avons déjà vu les avantages du CPOLD, maintenant les inconvénients:

  • Duplication de fichiers
  • Duplication de code
  • Réduction dramatique de la lisibilité
  • Difficulté de grouper des modifications (pour une fonctionnalité par exemple)
  • Ai-je déjà mentionné la duplication?

Conclusion

Sommes-nous maintenant tous bien d’accord avec Brian pour dire que le contrôle de versions, c’est indispensable? Et que le CPOLD, c’est dépassé?

Dans une prochaine histoire, les enfants, nous verrons avec Brian quels sont les merveilleux outils à notre disposition: les « Version Control System » !


EDIT (05/06/2009): la totalité de cette article (cette première partie ainsi que les deux suivantes, qui ne seront pas publiées sous forme de billet) a été présentée à PyCON.fr. Vous trouverez les liens vers la présentation (en ligne, au format vidéo, et les sources) dans le billet « PyCON.fr: excellent!« 

Categories: (D)VCS Tags:

Django, sqlite et mod_wsgi, attention au piège!

14/03/2009 admin 2 commentaires

Tout d’abord, je tiens à préciser que le problème qui suit n’est pas limité à l’utilisation de django ou de mod_wsgi.

Le contexte

Utilisation de SQLite pour un projet django déployé sur mod_wsgi:

# settings.py
DATABASE_ENGINE = 'sqlite3'
DATABASE_NAME = '/opt/mysite/mysite.db'

Et voici les permissions sur le système de fichier:

-rw-rw-rw- 1 ohan ohan 29696 2009-03-14 13:30 mysite.db

Tous les répertoires parents sont eux en 755 (lecture et exécution), ce qui ne devrait donc poser aucun problème, même pour l’utilisateur utilisé par les processus apache/mod_wsgi.

Le problème

Lors de la première tentative d’accès à la base de donnée (par exemple en accédant à l’administration django), une erreur 500 INTERNAL SERVER ERROR est renvoyée, et dans le fichier de log d’apache:

OperationalError: unable to open database file

La solution

Lors de l’accès à un fichier de base de données, SQLite va créer un fichier journal qui lui servira (entre autres) à gérer les accès à cette base. Plus d’informations sur la page expliquant les méthodes de vérouillage: locking in sqlite v3.

Pour créer ce fichier, il faut donc que l’utilisateur puisse écrire dans le répertoire parent.

chmod a+rw /opt/mysite

Ce problème ne devrait se présenter que lors d’un déploiement en environnement de production pour un projet qui utilise SQLite, ou sur un environnement de test si, comme moi, vous préférez tester sur apache directement, et non sur le runserver.

Categories: django, mod_wsgi, sqlite Tags:

Checklist: différences entre MySQL et les modèles Django

02/03/2009 admin Comments off

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

  1. 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
  2. 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
  3. Les valeurs par défaut indiquées dans les modèles ne sont pas transmises dans les scripts de création des tables
  4. Les BooleanField sont représentés par des TINYINT de 1bit
  5. 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:

  1. Les commentaires sur les champs et tables ne sont pas traduits en help_text ou docstrings, il faudra donc les dupliquer manuellement
  2. Un champ ENUM sera représenté par un CharField
  3. Les tailles de champ ne sont pas respectées. Par exemple, un Charfield sera avec un max_length de 135 par défaut
  4. 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
  5. Les valeurs par défaut ne sont pas importées

Il y a deux derniers points à noter:

  1. 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
  2. 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!

Categories: django Tags: