> Modules non standards > Autres modules non standards > Accès sqlite3
Accès sqlite3
Permet l'utilisation d'une base sqlite : faire import sqlite3 pour utiliser le module.
Connection à une base existante ou à créer :
- con = sqlite3.connect('myFile.db') : crée une connection.
- con.close() : ferme la connection.
- con.commit() : committe les transactions.
- con.rollback() : fait un rollback sur les transactions.
- par défaut, la connection n'est pas en autocommit (il faut committer explicitement les ordres sql). Par contre, les ordres modifiant la structure de la base (comme par exemple création d'une table) font automatiquement un commit, comme habituellement).
- con = sqlite3.connect('myFile.db', timeout = 1000) : fixe le timeout à 1000 s :
- le timeout est le temps au bout duquel, si on essaie de modifier la base et qu'une autre application la modifie aussi (transaction non committé), alors une exception est renvoyée (sqlite3.OperationalError).
- le timeout par défaut est de 5 secondes.
On peut faire une base en mémoire plutôt que sur le disque :
- con = sqlite3.connect(':memory:')
La valeur correspondant à null en sql est None en python.
Exécution d'ordres :
- on crée un curseur, on exécute l'ordre et on ferme le curseur :
cur = con.cursor()
cur.execute('create table myTable(x integer, y text)')
cur.close()
- exécution d'un ordre avec des liaisons (bindings) :
cur = con.cursor()
data = [[1, 'aaa'], [2, 'bbb'], [3, 'ccc']]
for d in data:
cur.execute("insert into myTable (x, y) values (?, ?)", d)
cur.close()
(éviter de construire un chaîne avec les valeurs pour des raisons de sécurité, pour éviter les injections sql).
- si un seul paramètre, ne pas oublier de fournir quand même une séquence. Par exemple cur.execute("insert into myTable (x) values (?)", (2, ) ou alors cur.execute("insert into myTable (x) values (?)", [2].
- on peut utiliser aussi des liaisons nommées, avec un dictionnaire :
data = [{'x': 1, 'y2': 'aaa'}, {'x': 2, 'y2': 'bbb'}]
for d in data:
cur.execute("insert into myTable (x, y) values (:x, :y2)", d)
cur.close()
(le :x doit avoir même nom que la clef du dictionnaire, indépendamment du nom de la colonne)
- on peut exécuter un ordre avec une séquence de valeurs (chaque élément de la séquence ayant l'ensemble des valeurs nécessaires :
data = [[1, 'aaa'], [2, 'bbb']]
cur.executemany("insert into myTable (x, y) values (?, ?)", data)
cur.close()
- nombre de rows affectés peut être obtenu avec cur.rowcount. Attention, ce nombre est correct uniquement pour les insert/update/delete. Il vaut -1 pour les select.
- en fait, on peut aussi utiliser directement execute et executemany avec la connection sans ouvrir explicitement de curseur, c'est un raccourci, par exemple : con.executemany("insert into myTable (x, y) values (?, ?)", data).
Requêtes en select :
- on peut faire un select et récupérer les résultats un à un :
cur = con.cursor()
cur.execute('select x, y from myTable')
row = cur.fetchone()
while row != None:
print(row)
row = cur.fetchone()
cur.close()
Chaque row récupéré a par exemple le format (1, u'aaa').
- fetchone renvoie None si pas de résultat.
- pour récupérer les tuples un à un, on peut aussi faire simplement :
cur = con.cursor()
cur.execute('select x, y from myTable')
for row in cur:
print(row)
cur.close()
- on peut aussi récupérer les résultats n par n, par exemple 2 par 2 :
cur = con.cursor()
cur.execute('select x, y from myTable')
rows = cur.fetchmany(2)
while len(rows) != 0:
print(rows)
rows = cur.fetchmany(2)
cur.close()
. Les rows sont récupérés sous la forme [(1, u'aaa'), (2, u'bbb')]
- on peut aussi récupérer l'ensemble des résultats en une seule liste :
cur = con.cursor()
cur.execute('select x, y from myTable')
rows = cur.fetchall()
print(rows)
cur.close()
. Les résultats sont récupérés sous la forme : [(1, u'aaa'), (2, u'bbb'), (3, u'ccc'), (4, u'ddd')]
- S'il y a des valeurs à passer en paramètre, on peut les passer comme pour toutes les requêtes en donnant une séquence pour les différents paramètres :
cur = con.cursor()
cur.execute('select x, y from myTable where x = ?', (3, ))
for row in cur:
print(row)
cur.close()
- accès des champs par nom : si avant d'ouvrir le curseur, on fait con.row_factory = sqlite3.Row, les résultats renvoyés seront des sqlite3.Row plutôt que des tuples :
con.row_factory = sqlite3.Row
cur = con.cursor()
cur.execute('select x, y from myTable')
row = cur.fetchone()
print(row.keys())
print(row['y'])
cur.close()
imprime les clefs (['x', 'y']) et la valeur du row associé au nom de colonne y (aaa). Pour revenir au mode normal, il suffit de faire con.row_factory = None.
Propriété text_factory :
- par défaut, myCon.text_factory est fixé à unicode et les valeurs renvoyées sont de type unicode (myCon est la variable qui contient la connection).
- on peut aussi mettre myCon.text_factory = str pour renvoyer seulement des chaînes ASCII.
- myCon.text_factory = sqlite3.OptimizedUnicode : renvoie de l'unicode seulement quand c'est nécessaire et sinon de l'ASCII.
Types supportés sous sqlite (indépendamment de python) :
- integer.
- real.
- text.
- blob.
Copyright python-simple.com
programmer en python, tutoriel python, graphes en python, Aymeric Duclert