La boîte à Tutoriels de Christopher PECAUD

Création d'une base Access avec Python

Laisser un commentaire

SOMMAIRE

I Introduction
II Prérequis
III Code
IV Conclusion

I Introduction

Dans ce document nous allons voir comment créer une base de données vide Access en utilisant le langage Python et le module Win32Com ainsi que le module comtypes. Pour l’exemple nous allons créer une base de contacts avec une table Contacts. Puis nous effectuerons un import de données dans cette table

II Prérequis

Pour utiliser ce module il faut installer Pywin32 en utilisant la ligne de commande Windows suivante :

Pip install pywin32

Une fois installé, vous allez pouvoir utiliser toutes les fonctionnalités de ce module y compris Win32Com. C’est-à-dire que vous pourrez interagir avec l’objet COM pour travailler avec les applications Windows comme ici avec Access.

Il faut de même installer le module comtypes avec la commande suivante :

Pip install comtypes

Ce module nous permettra de créer une instance de classe d’objet associé à l’application Access.

Un autre prérequis nécessaire pour travailler sur une base de données Access à partir d’un langage de programmation est l’installation du moteur de base de données Access 2016 par exemple. Vous pouvez le télécharger à l’adresse suivante : https://www.microsoft.com/en-us/download/details.aspx?id=54920

Au début du script vous devez effectuer les imports suivants :

from win32com.client import Dispatch

from comtypes.client import CreateObject

III Code

Code de la fonction create_db

Cette fonction a pour but de créer une base de données vide et la table Contacts associée. Cette fonction prend en paramètre le nom du fichier .accdb de la base de données à créer.

On commence par instancier un objet représentant l’application Access en appelant la fonction CreateObject incluse dans le module comtypes.

accApp = CreateObject('Access.Application')

Cette fonction prend en argument le nom de l’application. Ce qui va nous permettre d’avoir accès à toutes les fonctions et propriétés de l’instance d’objet accApp nouvellement créée.

On va importer ensuite le type Access généré dans le module comtypes.gen

From comtypes.gen import Access

On crée une instance de classe du moteur de base données d’Access en utilisant la ligne de commande suivante :

dbEngine = accApp.DBEngine

On crée ensuite la base de données à partir de l’instance d’objet Workspace nouvellement créé en utilisant la fonction Createdatabase comme ceci :

newdb = dbEngine.createDatabase(dbname, Access.DB_LANG_GENERAL)

Ensuite nous avons tous les éléments à notre disposition pour créer physiquement notre base de données sur le système en utilisant la fonction Createdatabase de l’instance d’objet « workspace » définie précédemment :

Nous pouvons alors créer nos tables en créant une requête SQL, ceci en utilisant la fonction Execute de l’objet base de données créé :

newdb.Execute("""CREATE TABLE Contacts(

                     ID autoincrement,

                     Nom varchar(50),

                     Prenom varchar(50),

                     Tel varchar(20),

                     Email varchar(100));""")

La fonction retourne les instances d’objets base de données et de l’application Access :

return newdb, accApp

Tout ce code est bien entendu encapsulé dans une structure try … except … finally

Pour finir dans le bloc finally on ferme la base de données et on ferme l’application Access. Puis on libère les ressources allouées aux différents objets créés dans cette fonctions comme ceci :

workspace = None

        dbEngine = None

Voici le code complet de la fonction :

def create_db(dbfilename):

    

    try:

    

        dbname = dbfilename

        accApp = CreateObject('Access.Application')



        from comtypes.gen import Access

        dbEngine = accApp.DBEngine

        

        #dbLangGeneral = ';LANGID=0x0409;CP=1252;COUNTRY=0'



        newdb = dbEngine.createDatabase(dbname, Access.DB_LANG_GENERAL)

        newdb.Execute("""CREATE TABLE Contacts(

                     ID autoincrement,

                     Nom varchar(50),

                     Prenom varchar(50),

                     Tel varchar(20),

                     Email varchar(100));""")

        

        

        return newdb, accApp

    except Exception as e:

        print(e)



    finally:



        workspace = None

        dbEngine = None

Je vous donne également le code de la fonction connectdb qui nous permet de nous connecter à la base de données sans la créer. Elle sera utile pour travailler dessus en cas de nouvel import de données ou de requête.

def connectdb(dbfilename):

    dbname = dbfilename

    accApp = CreateObject("Access.Application")

    dbEngine = accApp.DBEngine

    workspace = dbEngine.Workspaces(0)

    db = workspace.OpenDatabase(dbname)



    return db, accApp

La seule chose qui change est l’appel de la méthode Opendatabase de l’objet Workspace pour simplement ouvrir le fichier associé à la base de données fourni en paramètre de celle-ci.

La fonction d’importation des données

Cette fonction va nous permettre d’utiliser un objet de type Recordset pour importer des données dans la base de données.

Pour commencer la fonction prend en argument l’instance d’objet base de données DAO que nous venons de créer dans la partie précédente, ensuite l’instance de l’objet Application Access ainsi que les données à importées dans un dictionnaire :

def importdata(db, accApp, data): 

Au sein du corps de cette fonction nous créons notre instance d’objet Recordset comme ceci :

rs = db.OpenRecordSet('Select * from Contacts')

En requêtant tous les champs de la table Contacts

On va parcourir ensuite toutes les données incluses dans notre structure de données data pour pouvoir effectuer l’importation de chaque enregistrement dans la base de données.

La structure de données data sera définie dans le programme principale il s’agit d’une variable de type liste de dictionnaires. Pour itérer chaque donnée on utilise une boucle while comme ceci :

while (i <= datalength - 1):

            print(i)

            datatoimport = data[i]

            rs.AddNew()



            for key, value in datatoimport.items():

                rs.Fields.Item(key).Value = value

            rs.Update()

            i += 1

Nous utilisons notre objet RecordSet pour importer chaque enregistrement dans la base. Pour ce faire on utilise la fonction AddNew. Chaque champ et sa valeur sont ensuite enregistrés en utilisant la ligne de commande :

rs.Fields.Item(key).Value = value

Cette fonction est imbriquée dans une boucle pour itérer chaque champ et sa valeur.

On n’oublie pas de valider les enregistrements en base de données avec la fonction Update de l’objet RecordSet.

Voici le code complet de la fonction :

def importdata(db, accApp, data):

    try:

        rs = db.OpenRecordSet('SELECT * FROM Contacts')

        i = 0



        datalength = len(data)

        while (i <= datalength - 1):

            print(i)

            datatoimport = data[i]

            rs.AddNew()



            for key, value in datatoimport.items():

                rs.Fields.Item(key).Value = value

            rs.Update()

            i += 1

            #rs.Fields.Item(key).Value = value

    except Exception as e:

        print(e)



    finally:

        rs = None

        db = None



        accApp.DoCmd.CloseDatabase

        accApp.Quit

        accApp = None

Le programme principal

Dans le programme principal nous pilotons la création de la base de données si elle n’existe pas ou l’ouverture de celle-ci si elle a déjà été créée auparavant. Nous testons la présence ou non du fichier de base données par l’intermédiaire de ce code :

 dbfilename = r'C:\Users\echrpec\desktop\Contacts.accdb'

    if (not os.path.exists(dbfilename)):

        db, accApp = create_db(dbfilename)

    else:

        db, accApp = connectdb(dbfilename)

Pour tester la présence d’un fichier dans l’environnement Windows nous utilisons l’objet de type path avec la méthode associée exists celle-ci renvoie un booléen ce qui nous permet d’appeler une de nos foncrtions créées dans la première partie de ce tutoriel.

Une fois cet appel effectué et la connexion à la base de données effective nous allons définir le dictionnaire de données à importer :

customers = [{"nom": "firstname1", "prenom" : "lastname1", "Tel" : "01-23-45-67-89", "email" : "email1@domain1.fr"},

                {"nom": "firstname2", "prenom" : "lastname2", "Tel" : "03-00-11-67-89", "email" : "email2@domain2.fr"},

                {"nom": "firstname3", "prenom" : "lastname3", "Tel" : "05-45-45-60-72", "email" : "email3@domain3.fr"}]

Une fois ceci défini nous pouvons appeler la fonction d’import des données :

importdata(db, accApp, customers)

Voici le code du programme principal :

if __name__ == '__main__':

    dbfilename = r'C:\Users\echrpec\desktop\Contacts.accdb'

    if (not os.path.exists(dbfilename)):

        db, accApp = create_db(dbfilename)

    else:

        db, accApp = connectdb(dbfilename)

    customers = [{"nom": "firstname1", "prenom" : "lastname1", "Tel" : "01-23-45-67-89", "email" : "email1@domain1.fr"},

                {"nom": "firstname2", "prenom" : "lastname2", "Tel" : "03-00-11-67-89", "email" : "email2@domain2.fr"},

                {"nom": "firstname3", "prenom" : "lastname3", "Tel" : "05-45-45-60-72", "email" : "email3@domain3.fr"}]



    importdata(db, accApp, customers)

IV Conclusion

Nous avons vu dans ce tutoriel comment créer une base de données Access vide et y importer ensuite des données en utilisant Python et le module win32com issu de pywin32. Il est assez simple de manipuler des bases de données en utilisant le modèle d'aaccès de base de données OLEDb.

blog comments powered by Disqus