[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,dometElementTree. - 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.xmlvers 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 classeSimpleCfg, 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_PATHpour 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
pickleetanydbm. - 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.
—-