4.5. Persistance

La persistance réfère à l’ensemble des outils permettant de sauvegarder et réutiliser des données ou un état du programme.

4.5.1. Base de données

Nous étudierons le cas de la base de données SQLite3, car il s’agit de la plus simple à mettre en place [1]. Toutefois, ce qui est décrit ici fonctionnera pour toutes les bases de données, comme Python fournit une interface identique pour toutes.

Pour comprendre totalement la section qui suit, il est nécessaire d’avoir des notions sur les bases de données et le langage SQL.

La première chose à faire, après avoir importé le module sqlite3, est de créer un objet Connection qui représente une base de données :

>>> db = sqlite3.connect('database.sqlite3')

Note

Il est possible d’utiliser l’argument spécial ':memory:' afin de créer une base de données virtuelles, qui sera détruite une fois fermée. Cette technique peut être utile en vue de tester.

Afin d’exécuter une requête, il faut créer un objet Cursor et utiliser a méthode execute() :

>>> curs = db.cursor()
>>> curs.execute('create table persons (name, age)')
<sqlite3.Cursor object at ...>
>>> curs.execute('''insert into persons values('Jean', '21')''')
<sqlite3.Cursor object at ...>
>>> db.commit()
>>> curs.close()

Il est important de valider les requêtes avec la méthode commit() puis de fermer le curseur afin de ne pas gaspiller de la mémoire. Le curseur retourné par execute() n’a pas une grande utilité.

Il peut être dangereux d’insérer directement la valeur d’une variable dans une requête. À la place, il faut utiliser le symbole ? et fournir les variables en arguments supplémentaires à execure() :

>>> curs = db.cursor()
>>> name = 'Jean'
>>> param = (name,)
>>> curs.execute('select * from persons where name=?', param)
<sqlite3.Cursor object at ...>
>>> params = ('Michel', '10')
>>> curs.execute('insert into persons values(?, ?)', params)
<sqlite3.Cursor object at ...>
>>> db.commit()

Après une requête select, il est possible d’accéder aux données en utilisant le curseur comme un itérateur, ou en utilisant les méthodes Cursor.fetchone() ou Cursor.fetchall().

>>> curs.execute('select * from persons')
<sqlite3.Cursor object at ...>
>>> for row in curs:
...     print(row)
('Jean', '21')
('Michel', '10')

Voir aussi

http://www.sqlite.org
Le site officiel de SQLite : la documentation sur ce dernier décrit la syntaxe et les types disponibles.

PEP 249 — Database API Specification 2.0

4.5.2. Sérialisation

La sérialisation consiste à stocker n’importe quel objet dans un fichier, ce qui permet de le réutiliser ultérieurement, même si le programme a été interrompu entre temps. Généralement, le stockage sera effectué en binaire.

4.5.2.1. Pickle

Le module pickle permet de transformer des objets en bytes. De fait, lorsque qu’un fichier sera requis, ce dernier devra être ouvert en mode binaire.

pickle.dump(obj, file)

Sérialise obj et écrit sa représentation dans le fichier file.

pickle.load(file)

Lit une représentation sérialisée d’un objet dans le fichier file et retourne l’objet original.

Deux classes permettent de désigner une fois pour toute le fichier considéré : Pickler(file) (qui possède une méthode dump()) et Unpickler(file) (qui possède une méthode load()).

Warning

Tous les objets ne peuvent pas être sérialisés.

Il est possible de modifier le comportement d’une classe lorsqu’elle est (dé)sérialisée grâce à plusieurs méthodes :

  • __getnewargs__() qui définit quels arguments seront passés à __new__().
  • Les méthodes __getstate__() et __setstate__() permettent de modifier la manière dont le dictionnaire __dict__ est géré.

Il convient de noter que la méthode __init__() n’est généralement pas appelée lorsqu’un objet est désérialisé.

4.5.2.2. Shelve

À la différence de pickle, le module shelve permet de sérialiser plusieurs objets dans un même fichier : ces derniers sont accessibles via un système de clés, comme pour un dictionnaire [2].

shelve.open(filename)

Ouvre un dictionnaire persistant dans lequel sera stocké les données. Ce dernier possède les mêmes méthodes que les dictionnaires dict.

Shelf.sync()

Synchronise tous les changements mis en cache. Il est nécessaire d’appeler cette méthode pour que les changements soient écrits dans le fichier.

Shelf.close()

Cette méthode appelle sync() avant de fermer le dictionnaire.

Footnotes

[1]Une base de données SQLite consiste en un simple fichier sur le disque dur, au contraire de la plupart des autres bases de données qui font appel à tout un attirail pour fonctionner.
[2]“Shelf” veut d’ailleurs dire “étagère” en anglais.

Table des matières

Sujet précédent

4.4. Classes étendues

Sujet suivant

4.6. Internationalisation et localisation

Cette page