#!⌨

OpenERP : démystification du stockage des pièces jointes

OpenERP propose de stocker des fichiers. Par exemple, lorsqu'on génère un rendu de facture, celle ci est stockée et n'est pas générée à chaque fois qu'on cherche à l'imprimer. Par défaut, ces fichiers sont stockés en base de données. Le stockage en base de données peut s'avérer périlleux : une fois que vous aurez atteint 10000 factures clients, à coup de 50 ko par facture, cela nous fait un total 500 Mo. Et c'est sans compter les devis, les factures fournisseurs, les fichiers de la base de connaissances, et tout un tas de pièces jointe (en effet, une fois que le module document est installé, OpenERP vous propose de stocker des pièces jointes partout...) !

Stocker ces fichiers en base de données fait donc grossir notre base jusqu'à ce qu'elle pèse plusieurs centaines de méga-octets (voir de giga-octets). Cette pratique est périlleuse car elle augmente forcèment le temps de sauvegarde de la base de données, et ça alourdit le serveur de bases de données.

Heureusement, les développeurs d'OpenERP ont pensé à ce cas, en proposant de placer ces éléments sur le système de fichier. C'est assez pratique mais pas du tout documenté. Seule cette question sur le forum d'OpenERP nous met sur la route.

La solution consiste à enregistrer la clée ir_attachment.location à file:///filestore dans un objet ir.config_parameter. Hum... Le post nous indique où aller : dans le menu principal Settings puis dans les menus latéraux Technical->Parameters->System parameters. Par contre, il faut d'une part activer les Caractéristiques techniques pour accéder à ce menu, puis, d'autre part, être Administrateur pour activer le bouton d'ajout. Cette clef n'accepte pour l'instant qu'une valeur de la forme file:chemin, par contre on pourrait imaginer créer un module avec d'autres systèmes de stockage. Et du coup, vous pouvez également mettre le nom que vous voulez à la place de filestore.

Pour retrouver nos fichiers, ce n'est pas plus documenté. En allant voir dans le code, on se rend compte que la valeur après le file: est nettoyée et ajoutée à un root_path définit dans la configuration. Le nettoyage rend impossible de spécifier un dossier en dehors du root_path. Ce root_path correspond au chemin du module python openerp. Si vous avez récupéré OpenERP par son dépôt Bazaar, vous n'aurez aucun problème (il s'agit du dossier openobject-server/openerp). En revanche, si vous utilisez le paquet Debian, il faudra le rechercher. Une simple console python est nécessaire :

>>> import openerp
>>> openerp.__file__
'/usr/lib/pymodules/python2.6/openerp/__init__.pyc'
>>>

Si notre clef est spécifiée à file:///filestore, le dossier de stockage est alors /usr/lib/pymodules/python2.6/openerp/filestore. Par contre, ce n'est pas très recommandé de stocker des fichiers dans le dossier /usr/lib. D'après le Filesystem Hierarchy Standard, il vaudrait mieux stocker ces fichiers dans /var. Pour ce faire, j'utilise un lien symbolique :

ln -s /var/lib/openerp/filestore/ /usr/lib/pymodules/python2.6/openerp/filestore

Pour terminer, la hiérarchie de ce dossier est plutôt simple : on va retrouver comme premier niveau de sous dossier un dossier dont le nom correspond à la base de données OpenERP utilisée. Ensuite, viennent des sous dossiers dont les noms correspondent aux trois premiers caractères d'un hash SHA1 du contenu de notre fichier, puis dans ce dossier, notre fichier avec comme nom le hash SHA1 de son contenu (voir le code source). Cette information est stockée dans le champ store_fname de l'objet ir.attachment correspondant. De même, le nom réel du fichier est stockée dans le champ datas_fname.

Pour conclure, stocker ses fichiers sur le système de fichier plutôt qu'en base permet d'alléger la base de données. Par contre, il faut y penser pour la sauvegarde des données et lorsqu'on rajoute une instance d'OpenERP. Il faudra mettre en place des partages de système de fichier, ce qui peut s'avérer assez fastidieux...