Home

Tuesday, February 2 2010

Doctrine generate migrations or how to upgrade your database in production

Doctrine migration

4 months ago, you published a website on a production server. Ok, no a big deal. You work on next iterations and today you must update the website.

Some git push here, git pull there (or whatever you use). Still ok. But what about the database ? You did upgade you schema, still you cannot delete all existing datas in the production database, right ?

How should you manage that ? Check every field you changed, go to phpMyAdmin and manually build each field and table, launch functional tests to check no error appears ? Come on, let's not get silly ! You'll use Doctrine migration task !


Starting up the project

One upon a time your schema was straight and clear. You basically has a list of members with a fistname and a lastname

Schema at its first version

Member:
  columns:
    id:         { type: integer(4), primary: true, autoincrement: true }
    firstname:  string(50)
    lastname:   string(50)

Of course you had some basic fixtures :

Member:
  pointbar:
    firstname:  Stéphane
    lastname:   Langlois
  ioo:
    firstname:  Lionel
    lastname:   Chanson
  vinyll:
    firstname:  Vincent
    lastname:   Agnano

Then you did something like :

symfony doctrine:build --all --and-load

Made your modules, wrote your tests, refactored, enjoyed, had lunch and fun, pushed your site on the staging, got it tested and validated and finally run it in production ! Phew, what a journey you had.

Some time later, you reached today. And today is a great new day because you must update your website. And its database. Push all that in production. Oh, and preserving the datas from that database. Ok ok, you got the point and its issue. Let's go then !

Updating the project

Members are required to get username. A new functionality also comes up as they may have tasks. Easy...

First thing first, you update your schema as necessary :

Task:
  columns:
    id:         { type: integer(4), primary: true, autoincrement: true }
    title:      string(100)
    body:       clob
    member_id:  integer(4)
  relations:
    Member:
      class:        Member
      local:        member_id
      foreign:      id
      foreignAlias: Tasks

Member:
  columns:
    id:         { type: integer(4), primary: true, autoincrement: true }
    firstname:  string(50)
    lastname:   string(50)
    username:   string(20)

And update your fixtures :

Member:
  pointbar:
    username:   pointbar
    firstname:  Stéphane
    lastname:   Langlois
  ioo:
    username:   ioo
    firstname:  Lionel
    lastname:   Chanson
  vinyll:
    username:   vinyll
    firstname:  Vincent
    lastname:   Agnano
    
Task: 
  migrations:
    title:    Finish blog article
    body:     Will I ever make it ?
    Member:   vinyll
  mediabrowser:
    title:    Fix sfMediaBrowser tickets
    body:     "Ask some Windows to solve http://github.com/vinyll/sfMediaBrowserPlugin/issues/issue/5"
    Member:   vinyll

Update your model

Here is the point. Don't update your schema as you're used to as it would fully recreate your model.

Instead, you'll use the migration generation from difference.

Generating a migration

As of Doctrine 1.1, you can generate migrations classes automatically from schema differences and not type the whole thing. Warning : Do NOT run some "symfony doctrine:build --model" if you don't want to run through some error.

So you may safely hit this line :

symfony doctrine:generate-migrations-diff

Magic comes out and as the tasks says, it generates migration classes from the differences.

Check out /lib/migration/doctrine/ and you'll see 2 new files (2 in our example case). Those are the classes that will updagrade-enable and downgrade-enable our application without reconstructing the whole structure. The first generated file is the basic columns modification while the second is for indexes and relations (as it must be done after columns creation/deletion, database-wise).

Applying a migration

Simply run !

symfony doctrine:migrate

What happened ?

Check out your Base model classes and your database. They have been updated, just as if you had run a "doctrine:build --all" but with the awareness of versionning. We could compare it to svn or git.


Doctrine's versionning system

It actually happens in 2 places :

  • One that holds the current version : that's your database ! If you have a look at it, you'll see a table called "migration_version" that has 1 column named "version" and 1 record that holds "2" ("2" in our specific case). That "2" is as you understood the current version you are at !
  • The file system : these classes you opened earlier (/lib/migration/doctrine/*) are named by their version number.

Therefore it will be very easy to know at what version you currently are, how far your are from head version and what happens in next/previous version just reading the class files.

Update in staging/prod environment

You'll be required to migrate your prod version as well. First update your files going for a "git pull" or whatever. That brings in your migration classes. Next you just need to run your migration task :

symfony doctrine:migrate

Now you may run your tests again. All datas are preserved. You can go back for lunch and fun.

You may freely comment or tweet me.

Tuesday, January 19 2010

Time machine à la mano pour un site Web

ds210j
En quelques semaines, le disque dur de mon pwG4 est passé en mode casserole et les pistons de ma 306 ont gaufrés leurs soupapes - #fail
J'ai regardé mon vieux serveur de backup... prise de conscience... et achat rapide d'un petit NAS[1].

Pas convaincu par la wonderful ajax webadmin de synology, j'ai préféré une solution de backup incrémental avec rsnapshot. L'occasion de poster un billet éclair.

rsnapshot


rsnapshot, basé sur rsync, permet de prendre des instantanés d'un système de fichiers à un moment T. Il créé l'illusion de multiples sauvegardes complètes mais n'occupe, en réalité, qu'une seule sauvegarde accompagnée des incréments.

Facile à mettre en place, c'est une solution plutôt souple et efficace pour garantir l'intégrité des sites Web versatiles.

Installation et configuration

Quelques scripts perl à télécharger et le tour est presque joué.
Tuning du fichier de conf. /etc/rsnapshot.conf :

On spéc. la racine du répertoire de backup :

# All snapshots will be stored under this root directory.
snapshot_root   /mnt/backup

On spéc. les snapshots, ici :
2 par jour
7 jours sur 7
1 par semaine
et les 3 derniers mois

#########################################
#           BACKUP INTERVALS            #
# Must be unique and in ascending order #
# i.e. hourly, daily, weekly, etc.      #
#########################################

interval        hourly  2
interval        daily   7
interval        weekly  4
interval        monthly 3

On en profite pour exclure les lourdos :

# The include_file and exclude_file parameters, if enabled, simply get
# passed directly to rsync. Please look up the --include-from and
# --exclude-from options in the rsync man page for more details.
#
#include_file   /path/to/include/file
exclude_file    /mnt/backup/exclude

Avec dans /mnt/backup/exclude des trucs du genre :

cache/

Pour être cohérent avec le précédent billet sur l'accès sécurisé au serveur on spéc. le port :

ssh_args        -p 10068

Enfin, le coeur, on spéc. l'adresse du distant et le lien relatif sur le local :

# EXAMPLE.COM
#backup root@example.com:/etc/  example.com/
backup  particul@88.191.38.139:/www/ particul.es/

Pour les pépins de passphrase et d'authentification par clé : La-Nuit-des-morts-vivants

Test et automatisation

Pour tester la validité du fichier de config :

.-$ rsnapshot configtest

Pour tirer à blanc :

rsnapshot -t hourly

Reste plus qu'à croner :

.-$ sudo crontab -e 

0 */12 * * * /usr/local/bin/rsnapshot hourly
50 3 * * *  /usr/local/bin/rsnapshot daily
40 2 * * 6  /usr/local/bin/rsnapshot weekly
30 1 1 * *  /usr/local/bin/rsnapshot monthly

Résultat

Nous disposons de snapshots où les sauvegardes sont stockées. Les dossiers sont créés pour les différents intervalles qui ont été définis. Après quelques mois, le dossier de backup devrait ressembler à çà :

.-$ rsnapshot du particul.es/
5.2G    /.snapshots/hourly.0/particul.es/
5.4M    /.snapshots/hourly.1/particul.es/
5.4M    /.snapshots/daily.0/particul.es/
728M    /.snapshots/daily.1/particul.es/
4.8M    /.snapshots/daily.2/particul.es/
4.8M    /.snapshots/daily.3/particul.es/
6.2M    /.snapshots/daily.4/particul.es/
4.8M    /.snapshots/daily.5/particul.es/
4.8M    /.snapshots/daily.6/particul.es/
12M     /.snapshots/weekly.0/particul.es/
5.3M    /.snapshots/weekly.1/particul.es/
5.4M    /.snapshots/weekly.2/particul.es/
4.9M    /.snapshots/weekly.3/particul.es/
4.8M    /.snapshots/monthly.0/particul.es/
120M     /.snapshots/monthly.1/particul.es/
5.3M    /.snapshots/monthly.2/particul.es/
6.0G    total

Sauvegarde SQL

Ne pas oublier de sauvegarder la BD du site, une petit ajout dans le fichier de conf :

$.- vi /etc/rsnapshot.conf

backup_script ssh particul@88.191.38.139 mysqldump -u particul --password=s|<1llz --quick --single-transaction particul | /bin/gzip >| ./mysqldump.gz

Conclusion

Quelques liens devraient suffire pour clôturer le post...

Rsnapshot est très largement inspiré de l'article de Mike Rubel
Un petit livre pour aller plus loin.

See ya !!!

Tuesday, January 5 2010

Poste de développeur symfony à Nice

L'Agence Pix recherche un développeur symfony confirmé pour démarrer dès janvier 2010 sur un projet de grosse envergure.

Votre rôle

Avec le directeur multimédia de l'agence et l'équipe technique, vous travaillerez sur les aspects suivants :

  • conseil fonctionnel auprès du client
  • conception et rédaction du cahier des charges technique
  • développement
  • maintenance et suivi

skills

  • développeur symfony confirmé (1 an minimum)
  • bonne connaissance d'un framework javascript
  • passionné par les nouvelles technologies

Le site de l'agence : http://www.agencepix.com/

Envoyez votre candidature à : recrutement(chez)agencepix(.)com

Thursday, December 10 2009

sfCheckOut : svn co symfony tags

Un bon développeur est un flemmard.

J'en ai eu marre de taper svn co blabla bla pour récupérer les tags de symfony. Alors me suis fait un script en bash rapide.

Et comme vous êtes encore plus flemmard que moi[1] vous n'avez plus qu'à télécharger la source dispo en fin de billet.

Pour l'installer rien de plus simple. Copiez-là dans votre dossier /usr/bin ou autre endroit de votre $PATH. Un petit chmod a+x sfCheckOut et voilà y a plus qu'à.

La commande attend comme paramètre la version de symfony qui vous intéresse. Elle crée un dossier avec le numéro de version dans le répertoire courant où vous l'exécutez

[ioo@particul.es:/home/ioo]sfCheckOut 1.4.1

#installe la version 1.4.1 dans le répertoire courant ( /home/ioo/ )

[ioo@particul.es:/home/ioo] ls -la
drwxr-xr-x  7 ioo ioo 4096 déc.  10 00:06  1.4.1

Pour ceux qui voudrait installer ceci dans un répertoire type sfProjet/lib/vendor/symfony vous pouvez facilement remplacer la ligne[2]

#checkout de svn
if svn co $URL $VERSION

par :

#checkout de svn
if svn co $URL symfony

Amusez-vous bien ! Et pour ceux qui sont sur Montpellier ce Jeudi 10 Décembre je vous rappelle le qu'il y a un le sfPot 1.4

Notes

[1] Je viens quand même de dire implicitement meilleur, c'est pas gentil ?

[2] Le répertoire courant ici doit être /lib/vendor/

Saturday, December 5 2009

sfPot 1.4 à montpellier !

C'est l'heure codeur.


Alors que les releases de symfony suivent le même rythme que les sfPot de montpellier... bon d'accord c'est l'inverse, et pourtant vu la différence de travail :D

Ce sera une bonne occasion de discuter de la dernière release 1.4 de symfony et de la dernière feature dont vous êtes tombé amoureux.

Olivier Loynet propose de faire un petit plugin sfFoodPlugin pour l'occasion. Pour cela merci de me faire un retour pour que je réserve dans un restaurant : lionel.chanson [quelque part à] particul.es. Pour le resto je pensais au Chat Perché.

Ce sfPot[1] se tient ce jeudi 10 Décembre, encore et toujours au ShakeSpeare à partir de 18h30.

A jeudi !

Notes

[1] Est-ce que Lexik sera encore en surnombre ?

Wednesday, November 11 2009

Workshop Scrum les 2, 3 et 4 décembre prochains par Claude Aubry

scrum-aubry

Formation Scrum animée par Claude Aubry


Cette formation s'adresse à des équipes qui veulent appliquer Scrum. Elle leur permet de démarrer le projet dans de bonnes conditions.
La formation s'appuie sur Scrum et inclut des pratiques de XP comme les histoires d'utilisateur (user stories) et le pilotage par les tests d'acceptation (ATDD).
l'objectif étant de fournir les pistes suffisantes pour se lancer dans un projet web Python.

Pour s'inscrire - (8 stagiaires max.)
Le programme.
Présentation du stage.

Contact :
stephane.langlois {at} particul.es : +33 (0) 611 782 563

Monday, November 2 2009

Formation Django les 18, 19 et 20 novembre prochains par David Larlet

django-logo

Formation Django animée par David Larlet


Cette formation s'adresse à des développeurs curieux de découvrir les possibilités de Python pour le Web de l'origine du projet à la mise en ligne.

L'accent sera mis sur Django mais des outils Python d'administration système seront aussi mis en pratique au cours de la formation,
l'objectif étant de fournir les pistes suffisantes pour se lancer dans un projet web Python.

Pour s'inscrire - (8 stagiaires max.)
Le programme.
Présentation du stage.

Contact :
stephane.langlois {at} particul.es : +33 (0) 611 782 563

Thursday, October 29 2009

Retour sur la présentation scrumpy, formation Django et workshop Scrum

logo-scrumpy
Vendredi 23 octobre, les aventuriers qui ont réussi à déjouer les travaux de Clapiers ont pu assister à la conférence scrumpy. L'occasion de se retrouver, de se rencontrer, pour partager la qualité et la clarté des interventions de Claude Aubry et David Larlet.

Un joli voyage dans le monde de Python, Scrum et Django sous forme de pomodori sessions.

Quelques comptes rendus ont poussé sur le web :
- celui de Loïc Mathaud
- et Alexis Métaireau
- ou encore le blog : Are you agile ?


Nous attendons maintenant avec impatience les vidéos de M. Morzy, retenu dans l'enfer du micro-cinéma. Réception des livrables : semaine prochaine.

Pour patienter Claude Aubry vous propose de replonger dans la conférence en téléchargeant les slides de ses interventions.

Pour faciliter l'immersion, la prez de Nicolas Perriault est également disponible.

Surveillez également Biologeek ; les slides de David Larlet devrait bientôt faire leur apparition.

Un grand merci à David Larlet, Claude Aubry, Nicolas Perriault, Vincent Agnano, Mathieu Vilcot, Lionel Chanson, Jeremy Barthe, Mathieu Tricoire, Loïc Mathaud, Olivier Loynet, Cyril Esnos, Daniel Blanc, IOcean, Wonderful, Capstan, Inra, Neosysteme, Marcopolis, Kokora, Normind, Pyxis, PopDev, ThinkDry, La Souris Verte et ++

Workshops Scrum et formation Django


La présentation Scrumpy est terminée... :-( mais, les ateliers de formations démarrent... ;-)

Inscrivez-vous rapidement (8 stagiaires max.), à l'une ou l'autre des sessions (ou soyez fo{u,lle} venez aux deux) :

Formation Django animée par David Larlet : les 18, 19 et 20 novembre prochains

S'inscrire
Pour en savoir plus

Formation Scrum animée par Claude Aubry : les 2, 3 et 4 décembre prochains

S'inscrire
Renseignements complémentaires

N'hésitez pas à nous contacter pour d'éventuels renseignements complémentaires :
stephane.langlois [at] particul.es - +33 (0) 611 782 563

- page 1 of 8