BibliosData

[wiki: Stockage et manipulation de données]

—-

Module tarfile

Gestion des fichiers TAR, plutôt archivage.

  • open(path, mode) : ecriture / lecture d’un fichier.
  • close() : ferme le fichier actuel.
  • add(path) : ajoute un élément dans le fichier actuel.
  • getnames() : liste des éléments dans le fichier actuel.
  • extract(path, dest) : extraction d’un élément vers destination.

Exercices

  • Créez un fichier TAR contenant tous les fichiers d’une arborescence de votre choix.
  • Listez les éléments contenus dans un fichier TAR.
  • Extraire un élément pour chaque type de fichier.
  • Vérifiez que vous arrivez à ouvrir les fichiers avec les outils « standards » de Windows.
#!html
<br clear=right>

—-

Module zipfile

Gestion des fichiers ZIP, plutôt compression.

  • ZipFile(path, mode) : ecriture / lecture d’un fichier.
  • close() : fermeture du fichier actuel.
  • write(path) : exécute compression et insertion dans fichier actuel.
  • namelist() : liste des éléments stockés dans fichier actuel.
  • getinfo(path) : informations d’un élément dans fichier actuel.
  • read(path) : extraction d’un élément.

Exercices

  • Créez un fichier ZIP contenant tous les fichiers d’une arborescence de votre choix.
  • Listez les éléments contenus dans un fichier ZIP.
  • Extraire un élément pour chaque type de fichier.
  • Vérifiez que vous arrivez à ouvrir les fichiers avec les outils « standards » de Windows.
#!html
<br clear=right>

—-

Module csv

Un fichier CSV est un fichier textuel dont chaque ligne est composée de valeurs séparées par des tabulations, ou des « , », « ; » …

  • DictReader() : lit un fichier CSV.
  • Sniffer() : détecte le dialecte.
  • DictWriter() : ouvre nouveau fichier CSV.
  • writerow() : ecrit une ligne de données.
  • Manipulation de dictionnaires de données :
  • dict_csv['key'] =
  • Méthodes classiques, tri, insertion, etc.
  • Supporte si données en trop ou manquante.

Exercice de manipulation du fichier de données [raw-attachment:short_ex.csv short_ex.csv].

  • Utiliser un dialecte.
  • Chargez le dictionnaire de données.
  • Rajoutez, modifiez des données au dictionnaire.
  • Enregistrez les données dans un autre fichier.
  • Vérifiez que votre nouveau fichier correspond à ce que vous vouliez, sous Excel par exemple, ou un simple éditeur de texte.

(s’inspirer de l’exemple [raw-attachment:code_csv.py code_csv.py])

#!html
<br clear=right>

—-

Modules XML

Fichier XML

  • EXtensible Markup Language.
  • Stockage informations de manière arborescente.
  • Idéal pour fichiers de configuration.
  • Extensible : Vocabulaire et grammaire libres !
  • Générique : Employé pour tout type de données.
  • A l’origine d’autres formats : XHTML, SVG, … le vôtre … etc.
  • Peut être visualisé dans votre navigateur Web préféré.
  • Quelques règles à respecter … quand même !
  • Peut être validé par un fichier de déclaration : DTD.

Exemple simple :

<?xml version="1.0" encoding="utf-8" ?>
<config>
<author>Simon CHOLLET</author>
<email>s.chollet@llr.in2p3.fr</email>
<institut nom="LLR" address="Ecole Polytechnique - 91128 PALAISEAU" />
<date>09/09/2011</date>
<version>1.0</version>
</config>

Technologies XML

  • SAX (Simple Api for XML) : analyse du fichier « au fil de l’eau ». Consomme très peu de mémoire, le fichier n’est pas chargé complètement.
  • DOM (Document Object Model) : représentation orientée objet du contenu. Consomme beaucoup de mémoire si le fichier est gros. Le fichier est chargé et analysé complètement en une seule fois.
  • Python intègre les 2 technologies, modules : sax, dom et ElementTree.
  • De nombreux modules d’analyse de fichiers XML !
  • BeautifulSoup : accepte fichiers mal formés, très utile pour analyse fichiers XHTML, par exemple.

Exercices XML

  • Visualisez les fichiers [raw-attachment:config.xml config.xml] et [raw-attachment:simple.xml simple.xml] dans votre navigateur Web.
  • Regardez le contenu et la déclaration de l’arborescence des données, de ces mêmes fichiers dans un éditeur de texte.
  • Copiez le fichier simple.xml vers un nouveau fichier.
  • Ouvrir le nouveau fichier dans un éditeur de texte, ou éditeur de code.
  • Ajoutez une balise description, avec quelques attributs avec les valeurs que vous souhaitez.
  • Ajoutez du texte entre les balises description.
  • Visualisez votre nouveau fichier dans le navigateur Web.

Exercices SAX

  • Modifiez le code source du fichier [raw-attachment:config_xml.py config_xml.py] pour qu’il puisse prendre en compte la nouvelle balise : ajoutez l’attribut m_desc à la classe SimpleCfg, et modifiez la méthode d’extraction de données pour remplir le nouvel attribut.
  • Modifiez aussi la méthode de visualisation d’objet repr() pour qu’elle affiche le nouvel attribut.
  • Exécutez le programme [raw-attachment:code_sax_xml.py code_sax_xml.py] en modifiant la valeur de XML_SIMPLE_CFG_INPUT_PATH pour pointer vers le chemin du nouveau fichier XML.
  • Vérifiez que vous voyez votre nouvelle balise et attribut(s).

Exercices DOM

  • Fichier [raw-attachment:code_dom_xml.py code_dom_xml.py].
  • Revue de code …
  • Remarquez la manière de remplir les attributs de l’objet configuration.
  • Regardez les méthodes de création de branches.
#!html
<br clear=right>

—-

Bases de données

  • Principe de base : à chaque clé correspond un enregistrement.
  • Important de structurer ses données en pensant dés le début à la clé.
  • Beaucoup de modules existent.
  • Plusieurs manières d’accéder aux bases : sous forme de dictionnaires, d’objets, etc.
  • Base stockée dans fichier ou serveur.
  • Les choix possibles :
  • Fichier : pickle, shelve, SQLite.
  • Serveur : MySQL, SQLAlchemy, Storm.
  • Etc.
#!html
<br clear=right>

—-

Module anydbm

  • DBM : DataBase Manager.
  • Enregistrement de dictionnaires dans fichier.
  • Manipulation de dictionnaire : data[key] = valeur.
  • open() : Ouvre, crée fichier d’enregistrement.
  • close() : Ferme et enregistre le fichier.
  • keys() : Liste les clés disponibles.
  • del, remove() : Supprime enregistrement.

Exemple

import anydbm


villes = ['Dallas', 'Los Angeles', 'New York']
vols = ['1144', '1045', '1520']
horaires = ['14H30', '15H20', '16H20']

# Creation des fichiers DBM villes / horaires
villeDBM = anydbm.open('villes.db', 'n')
horaireDBM = anydbm.open('horaires.db', 'n')
# Ajout des entrees dans les fichiers
idx = 0
for vol in vols:
villeDBM[vol] = villes[idx]
horaireDBM[vol] = horaires[idx]
idx += 1

# Affichage des entrees de la base
print villeDBM.items()
print horaireDBM.items()

# Fermeture des fichiers
villeDBM.close()
horaireDBM.close()


#!html
<br clear=right>

—-

Module pickle/cPickle

  • Module qui sérialise les enregistrements.
  • Pas de notion de clé.
  • Enregistrements stockés les uns à la suite des autres dans le fichier.
  • Fonctionne avec des listes, dictionnaires, objets.
  • Peut utiliser un empaqueteur / dépaqueteur pour enregistrer et extraire les données.
  • Quand c’est disponible, préférez cPickle, écrit en C et plus rapide.
  • ATTENTION : pas de garantie de portabilité de vos données entre des plateformes différentes.
  • open() : Ouvre un fichier.
  • close() : Ferme et enregistre le fichier.
  • dump() : Insère des enregistrements.
  • Pickler() : Empaqueteur de données.
  • Unpickler() : Dépaqueteur de données.
  • load() : Charge des enregistrements.

Exemple 1

vols = {'1144':'Dallas', '1045':'Los Angeles', '1520':'New York'}
horaires = ['14H30', '15H20', '16H20']


# Ouverture du fichier
pkl_file = open(PICKLE_DATA_FILE, "w")

# Creation de l'empaqueteur
packer = pkl.Pickler(pkl_file)

# Enregistrement des donnees
packer.dump(vols)
packer.dump(horaires)
pkl_file.close()

# Lecture des entrees depuis un fichier
pkl_file = open(PICKLE_DATA_FILE, "r")

# Creation du depaqueteur
unpacker = pkl.Unpickler(pkl_file)

# Lecture des donnees
vols_read = unpacker.load()
horaires_read = unpacker.load()
pkl_file.close()


Exemple 2

img_gpib = ImageStore('CableGPIB', '../input/gpib.jpg')
img_oscillo = ImageStore('Oscilloscope', '../input/oscillo.jpg')


# Creation du dictionnaire
img_dict = {'gpib': img_gpib, 'oscillo': img_oscillo}
pkl_file = open(PICKLE_DATA_IMG_FILE, "w")
packer = pkl.Pickler(pkl_file)
packer.dump(img_dict)
pkl_file.close()

pkl_file = open(PICKLE_DATA_IMG_FILE, " r")
unpacker = pkl.Unpickler(pkl_file)
img_dict_read = unpacker.load()
pkl_file.close()
for item in img_dict_read:
img_tmp = img_dict_read[item]
# Contenu de l'image au format chaine de caracteres
img_txt = cStringIO.StringIO()
img_txt.write(img_tmp.m_img)
img_txt.seek(0)
# Enregistrement dans nouveau fichier
img = Image.open(img_txt)
img.save('../output/' + img_tmp.m_desc + '.jpg')


#!html
<br clear=right>

—-

Module shelve

  • Construit au-dessus des modules pickle et anydbm.
  • Accès aux enregistrements par clé, recouvre lacune du module pickle.
  • open() : ouvre un fichier et charge les enregistrements dans un dictionnaire.
  • keys() : liste les clés disponibles dans les enregistrements.
  • close() : ferme et enregistre le fichier.
  • Accès aux données directement comme nous l’aurions fait avec un dictionnaire : db[key].

Exemple

# Les donnees a ecrire
vols = {'1144':'Dallas', '1045':'Los Angeles', '1520':'New York'}
horaires = ['14H30', '15H20', '16H20']


# Creation du gestionnaire de BDD
db = shelve.open(SHELVE_DATA_FILE, 'n')

# Enregistrement des donnees
db['vols'] = vols
db['horaires'] = horaires

# Fermeture du gestionnaire de BDD
db.close()

# Lecture des entrees depuis un fichier
db = shelve.open(SHELVE_DATA_FILE, "r")

# Extraction des cles du fichier
for key in db.keys():
item = db[key]
print " %s: %s" % (key, item)

# Extraction d'une cle particuliere
print " * Vol 1144 :", db['vols']['1144']
db.close()


#!html
<br clear=right>

—-

Module SQLite

  • Utilise un fichier pour stocker les enregistrements, tout est dedans : la structure et les données.
  • Requêtes SQL au travers d’un « curseur » pour accéder aux données, les filtrer, en insérer, etc.
  • Nécessite de connaître la syntaxe SQL.
  • Performant d’un point de vue accès, les filtres sont effectués directement, juste le résultat est donné.
  • Principe :
  • Ouvrir la connexion.
  • Création d’un curseur de parcours de données.
  • Exécution des requêtes : commit.
  • Fermeture du curseur.
  • Fermeture de la connexion à la base.

Exemple

db = sqlite3.connect(SQLITE_DATA_FILE)


# Creation d'un curseur de parcours de donnees
cursor = db.cursor()

# Suppression de la table si elle existe
cursor.execute("DROP TABLE IF EXISTS persons")

# Creation de la table persons de l'annuaire
cursor.execute("""CREATE TABLE persons (ID int PRIMARY KEY ASC, title char(255), ...)""")

# Remplissage de la table
cursor.execute("""INSERT INTO persons VALUES ('1', 'Mr', 'DUPONT', 'Pierre', '1960 06 30' '30')""")

# Sauvegarde des changements
db.commit()

# Extraction des donnees
cursor.execute("SELECT * FROM persons")
for row in cursor:
# Affichage de la ligne
print " > %d, %s, %s, %s, %s, %d" % (row[0], row[1], row[2], row[3], row[4], row[5])

# Fermeture du curseur de parcours de donnees
cursor.close()
db.close()


Exercices :

  • Utilisez le fichier [raw-attachment:code_db_pickle.py code_db_pickle.py] pour rajouter une image dans la liste des images actuelles.
  • Vérifiez lorsque vous exécutez le programme que votre image se trouve bien dans le répertoire output.
  • Utilisez le fichier [raw-attachment:code_db_sqlite.py code_db_sqlite.py] pour (dans l’annuaire) :
  • Ajouter une personne.
  • Modifier une personne
  • Supprimer une personne.
  • Vérifiez, en exécutant le programme, que vos modifications ont été prises en compte.
#!html
<br clear=right>

—-

Module MySQLdb

  • Enregistrement des données sur un serveur.
  • Technologie très largement répandue, notamment dans les applications Web.
  • Accepte de gros volumes et flux de données.
  • Connaître la syntaxe des requêtes SQL …
  • Utilise le module externe MySQLdb.
  • Réagit dans mêmes principes que SQLite : au niveau de la connexion, du curseur, etc.

Exemple : voir [raw-attachment:code_db_mysql.py code_db_mysql.py]

#!html
<br clear=right>

—-

Module pySQLAchemy

Introduction

  • ORM : Object Relational Mapping.
  • Approche orientée objet.
  • La liste des enregistrements est reliée à une liste d’objets.
  • Chaque attribut d’une table de BDD devient un attribut d’objet.
  • Accepte plusieurs types d’interfaces : MySQL, SQLite, etc.
  • Un seul outil pour tous les types de base.
  • Permet facilement de manipuler les enregistrements.

Principe

  • Création classe représentant la structure d’un enregistrement.
  • Création d’un catalogue de données, et d’une table associée.
  • Association de la table et de la classe créée.
  • Connexion à la base de données (session).
  • Exécution des requêtes.
  • Fermeture de la connexion.

Fonctions

  • create_all() : création des tables.
  • drop_all() : supprime des tables.
  • mapper() : associe la table avec une classe.
  • add_all() : permet d’ajouter des enregistrements.
  • commit() : exécute les requêtes.
  • query() : effectue une demande à la base de données.
  • order_by() : trie les données selon un ou plusieurs critères.
  • Etc

Exemple : voir [raw-attachment:code_db_alchemy.py code_db_alchemy.py]

Exercices

  • Utilisez le fichier [raw-attachment:code_db_alchemy.py code_db_alchemy.py] pour :
  • Ajouter un champ à la base : group.
  • Faire de même pour la classe Person : m_group.
  • Modifier la méthode d’affichage de la classe.
  • Rajouter une ligne de visualisation de toutes les personnes de l’annuaire avec le nouveau champ.
  • Vérifiez que le programme fonctionne …
#!html
<br clear=right>

—-

Modules Storm / pyODBC

  • ODBC : Open DataBase Connectivity.
  • pyODBC :
  • Accepte de nombreux types de bases de données.
  • Fonctionne en déclarant un « driver ».
  • Surcouche générique (définie par le standard ODBC).
  • Storm :
  • ORM, comportement identique à pySQLAlchemy.
  • Ne prend pas des méthodes objet (query, order_by, etc.), mais exécute plutôt des requêtes SQL.
#!html
<br clear=right>

—-

Conclusions

Revue des technos de bases de données

  • anydbm : la base, le plus simple.
  • (c)pickle : permet une sérialisation des objets.
  • shelve : introduit la notion de clé en plus de la sérialisation.
  • SQLite : largement utilisé, puissance d’accès équivalente à MySQL.
  • MySQLdb : Permet de déporter sur serveur.
  • SQLAchemy : Approche orientée objet.
  • Exemple de sérialisation d’objet image [raw-attachment:code_db_pickle.py code_db_pickle.py].
  • Exemple d’utilisation Storm : [raw-attachment:code_db_storm.py code_db_storm.py].
  • Exemple d’utilisation pyODBC : [raw-attachment:code_db_odbc.py code_db_odbc.py].

Conclusions sur le stockage

  • Nous avons vu de nombreux moyens de stocker les données plus ou moins compressées d’une application.
  • Chaque technologie a ses avantages et inconvénients :
  • TAR : Archivage ++.
  • ZIP : Compression ++.
  • CSV : Outils de bureautique +.
  • XML : Configuration arborescente ++.
  • SQL : Flux et volumes de données ++.
  • Il faut cependant se préoccuper dans un premier temps de la structure des données d’une application, avant de se plonger tête baissée dans le codage !
  • L’approche orientée objet vue dans les différents modules rend la maintenance du code plus facile, flexible, partageable.

—-


Attachments