-
RMySQL : interface R pour MySQL
2016-07-30
Source(latest update : 2016-07-30 15:53:45)
La librairie
RMySQL(qui repose sur la librairieDBI) permet de se connecter à une base de données MySQL dans R, d’importer un tableau de la base de données dans R ou vice-versa, et d’exécuter des requêtes SQL dans la base de données à partir de R.Connexion à une base de données
Nous créons d’abord une nouvelle base de données dans MySQL. Pour cela, on lance MySQL dans un terminal avec la commande
mysql -u root -p, puis, après avoir saisi le mot de passe, on crée la base de donnéesrmysql0avec l’instructionCREATE DATABASE rmysql0;La première chose à faire pour utiliser
RMySQLest la connexion à la base de données, qu’on réalise ainsi :library(RMySQL) # connect to database (don't forget to disconnect) DB <- dbConnect(MySQL(), user="root", host="localhost", password="xxx", dbname="rmysql0")Il faudra penser à déconnecter en fin d’utilisation. Nous avons assigné la connexion à la variable
DB, qu’il faudra alors utiliser à chaque opération.Import/Export d’un tableau
La base de données que nous venons de créer est vide :
dbListTables(DB) # list tables ## character(0)Nous allons y ajouter le tableau de données R suivant :
df1 <- data.frame( Name = c("Joe", "Joe", "Bill", "Jim", "Kate"), Value = c(10.1, 13, 9, 7.7, -3), Indic = c(0L, 1L, 1L, 2L, 2L), Status = c("A", "A", "A", "B", "B") ) df1 ## Name Value Indic Status ## 1 Joe 10.1 0 A ## 2 Joe 13.0 1 A ## 3 Bill 9.0 1 A ## 4 Jim 7.7 2 B ## 5 Kate -3.0 2 BCela se réalise avec la fonction
dbWriteTable:dbWriteTable(DB, "dat1", df1) # write dataframe to the database ## [1] TRUENous avons nommé le tableau
dat1dans MySQL. Il apparaît maintenant dans la liste des tableaux de la base de données :dbListTables(DB) ## [1] "dat1"La fonction
dbListFieldsretourne les noms de ses colonnes :dbListFields(DB, "dat1") ## [1] "row_names" "Name" "Value" "Indic" "Status"Une colonne
row_namesa automatiquement été ajoutée par la fonctiondbWriteTable. Voilà le tableaudat1visualisé dans MySQL :mysql> SELECT * FROM dat1; +-----------+------+-------+-------+--------+ | row_names | Name | Value | Indic | Status | +-----------+------+-------+-------+--------+ | 1 | Joe | 10.1 | 0 | 0 | | 2 | Joe | 13 | 1 | 0 | | 3 | Bill | 9 | 1 | 0 | | 4 | Jim | 7.7 | 2 | 0 | | 5 | Kate | -3 | 2 | 0 | +-----------+------+-------+-------+--------+Si on ne veut pas la colonne
row_names, il faut utiliser l’optionrow.names=FALSElorsqu’on écrit le tableau :dbWriteTable(DB, "dat1", df1, row.names=FALSE).Pour importer un tableau de MySQL dans R, on utilise
dbReadTable:dbReadTable(DB, "dat1") # get database table as dataframe ## Name Value Indic Status ## 1 Joe 10.1 0 A ## 2 Joe 13.0 1 A ## 3 Bill 9.0 1 A ## 4 Jim 7.7 2 B ## 5 Kate -3.0 2 BNotez que la colonne
row_namesne se retrouve pas dans le tableau importé dans R.Exécuter une requête SQL
La librairie
RMySQLfournit deux fonctions pour exécuter une requête SQL sur un tableau :dbSendQueryetdbGetQuery.Fonction
dbGetQueryLa fonction
dbGetQueryenvoie une requête et retourne le résultat dans R. On peut l’utiliser par exemple pour la requêteDESCRIBE:dbGetQuery(DB, "DESCRIBE dat1") ## Field Type Null Key Default Extra ## 1 row_names text YES <NA> ## 2 Name text YES <NA> ## 3 Value double YES <NA> ## 4 Indic bigint(20) YES <NA> ## 5 Status text YES <NA>Ou pour une reqûete
SELECT:dbGetQuery(DB, "SELECT * FROM dat1 WHERE Name='Joe';") ## row_names Name Value Indic Status ## 1 1 Joe 10.1 0 A ## 2 2 Joe 13.0 1 ACela n’a pas altéré le tableau :
dbReadTable(DB, "dat1") ## Name Value Indic Status ## 1 Joe 10.1 0 A ## 2 Joe 13.0 1 A ## 3 Bill 9.0 1 A ## 4 Jim 7.7 2 B ## 5 Kate -3.0 2 BLa fonction
dbGetQueryne retourne rien lorsqu’on l’utilise pour exécuter une requête qui altère le tableau, telle queALTERouUPDATE:dbGetQuery(DB, "ALTER TABLE `dat1` DROP COLUMN `Name`") ## data frame with 0 columns and 0 rows dbGetQuery(DB, "UPDATE `dat1` SET `Value` = `Value`*2") ## data frame with 0 columns and 0 rowsCes requêtes ont bien été exécutées :
dbReadTable(DB, "dat1") ## Value Indic Status ## 1 20.2 0 A ## 2 26.0 1 A ## 3 18.0 1 A ## 4 15.4 2 B ## 5 -6.0 2 BIl vaut mieux utiliser la fonction
dbSendQuerypour exécuter ces requêtes.Fonction
dbSendQueryAvant d’illustrer la fonction
dbSendQuery, nous restaurons le tableau initial. Il faut d’abord l’effacer avecdbRemoveTable:dbRemoveTable(DB, "dat1") ## [1] TRUE dbWriteTable(DB, "dat1", df1) ## [1] TRUEExécutons la requête
ALTERcomme précédemment :dbSendQuery(DB, "ALTER TABLE `dat1` DROP COLUMN `Name`") ## <MySQLResult:31102696,3,18>La requête a été exécutée. La fonction
dbSendQueryretourne aussi un objet dans R : un “résultat”. Si on le stocke dans une variable, on peut obtenir des informations sur ce résultat :res <- dbSendQuery(DB, "UPDATE `dat1` SET `Value` = `Value`*2") dbGetStatement(res) ## [1] "UPDATE `dat1` SET `Value` = `Value`*2" dbGetRowsAffected(res) ## [1] 5La fonction
dbGetInforetourne toute une liste d’informations.La fonction
dbGetQueryvue précédemment est en fait équivalente àdbSendQuerysuivie dedbFetch:res <- dbSendQuery(DB, "SELECT * FROM dat1 WHERE Value > 20") dbColumnInfo(res) ## name Sclass type length ## 1 row_names character BLOB/TEXT 65535 ## 2 Value double DOUBLE 22 ## 3 Indic double BIGINT 20 ## 4 Status character BLOB/TEXT 65535 dbFetch(res) ## row_names Value Indic Status ## 1 1 20.2 0 A ## 2 2 26.0 1 AL’instruction
SELECTn’effectue pas de transformation sur le tableau de données. C’est pourquoi il faut assigner le résultat dedbSendQuerydans une variable lorsqu’on effectue une requêteSELECT. Par exemple le code suivant retourne une erreur, car une opération sur le tableau est en suspens :dbSendQuery(DB, "SELECT * FROM dat1 WHERE Value > 20") ## <MySQLResult:85042008,3,21> dbReadTable(DB, "dat1") ## Error in .local(conn, statement, ...): connection with pending rows, close resultSet before continuingAssigner le résultat dans une variable permet d’effacer le résultat avec la fonction
dbClearResult, ce qui annule l’opération en suspens :res <- dbSendQuery(DB, "SELECT * FROM dat1 WHERE Value > 20") dbClearResult(res) ## [1] TRUE dbReadTable(DB, "dat1") ## Value Indic Status ## 1 20.2 0 A ## 2 26.0 1 A ## 3 18.0 1 A ## 4 15.4 2 B ## 5 -6.0 2 BLa fonction
dbHasCompletedindique si un résultat est achevé ou non :res <- dbSendQuery(DB, "UPDATE `dat1` SET `Value` = `Value`*2") dbHasCompleted(res) ## [1] TRUE res <- dbSendQuery(DB, "SELECT * FROM dat1 WHERE Value > 20") dbHasCompleted(res) ## [1] FALSE dbClearResult(res) ## [1] TRUE dbHasCompleted(res) ## Error: Expired MySQLResultAnnuler une requête
Si on utilise la fonction
dbBeginavant d’exécuter une requête, on peut annuler cette requête avec la fonctiondbRollback. Par exemple :# SendQuery and Rollback dbBegin(DB) ## [1] TRUE res <- dbSendQuery(DB, "DELETE FROM dat1 WHERE Indic = 0") dbReadTable(DB, "dat1") # query is executed ## Value Indic Status ## 2 52.0 1 A ## 3 36.0 1 A ## 4 30.8 2 B ## 5 -12.0 2 B dbRollback(DB) ## [1] TRUE dbReadTable(DB, "dat1") # query is cancelled ## Value Indic Status ## 1 40.4 0 A ## 2 52.0 1 A ## 3 36.0 1 A ## 4 30.8 2 B ## 5 -12.0 2 B dbClearResult(res) ## [1] TRUEDéconnexion
dbDisconnect(DB) ## [1] TRUE
