'Push an R dataframe to SQL as a new table
I'm trying to make my analysis workflow more efficient connecting my SQL Server Database to R-Studio.
What I do now?
- I develop my queries using MS SQL Management Studio to extract relevant information for the analysis.
- I export the query result to a .csv UTF-8 file.
- I read the file in R-Studio and perform analyses.
- I export the final dataframe to a .csv UTF-8 file.
- I use this file to create a table back in SQL Management Studio.
What am I trying to do?
I want to create a connection between SQL Server and R-Studio so I can directly import/export my dataframe/table without having these files in my computer.
To do that I have followed these steps:
- Installed DBI and odbc packages in R.
- Configured the connection using "ODBC Data Source Connection Administrator"
- My connection name is "Enterprise" (SQL Server Native Client 10.0)
- In R-Studio, using the Connection tab, I can seen a list of data sources containing "Enterprise".
- Choosing "Enterprise" data source create an R object with the name "con" that contains the connection information.
- At this point I can see all databases in the connection tab.
- My code for testing in R is the following:
---
title: "R Notebook"
output: html_notebook
---
```{r setup, include=FALSE}
library(odbc)
con <- dbConnect(odbc::odbc(), "Enterprise", timeout = 10) ```
```{sql, connection = con, output.var = "DataFrame"}
SELECT TOP 1000 *
FROM [DB].[dbo].[Table] ```
Data<-DataFrame[1:100,1:10]
head(Data,11)```
Var1 Var2 Var3 Var4 Var5 Var6 Var7 Var8 Var9 Var10
A 1 2.4 5.5 13.1 30.8 72.4 170.5 401.6 945.7
B 2 4.7 11.1 26.1 61.5 144.8 341.1 803.2 1891.5
C 3 7.1 16.6 39.2 92.3 217.3 511.6 1204.8 2837.2
D 4 9.4 22.2 52.2 123.0 289.7 682.2 1606.4 3782.9
E 5 11.8 27.7 65.3 153.8 362.1 852.7 2008.0 4728.6
F 6 14.1 33.3 78.4 184.5 434.5 1023.2 2409.6 5674.4
G 7 16.5 38.8 91.4 215.3 506.9 1193.8 2811.2 6620.1
H 8 18.8 44.4 104.5 246.0 579.4 1364.3 3212.8 7565.8
I 9 21.2 49.9 117.5 276.8 651.8 1534.9 3614.4 8511.5
J 10 23.5 55.5 130.6 307.5 724.2 1705.4 4016.0 9457.3
K 11 25.9 61.0 143.6 338.3 796.6 1875.9 4417.6 10403.0
```{sql, connection = con}
SELECT * INTO [DB].[dbo].[New_Table]
FROM ?Data```
Here I'm using the ?
to indicate that "Data" is an R dataframe object in the SQL Chunk.
Error in vapply(values, function(x) { : values must be length 1,
but FUN(X[[1]]) result is length 100
Failed to execute SQL chunk
My guess is I'm doing something wrong in the last chunk.
What will be the proper way to push "Data" to my data base?
Solution 1:[1]
How I solved it?
I was on the right track until I got to the part of pushing my dataframe to the DB. @r2evans pointed out that I was trying to create a table from the server with information that only existed locally with this code:
```{sql, connection = con}
SELECT * INTO [DB].[dbo].[New_Table]
FROM ?Data```
At this point, I changed the method and tried to pushed the dataframe using r-code:
```{r}
dbWriteTable(con, "[DB].[dbo].[New_Table]", Data)```
The result was the following error:
nanodbc/nanodbc.cpp:1587: 42000: [Microsoft][SQL Server Native Client 10.0][SQL Server]CREATE TABLE permission denied in database 'master'.
The problem here: I was trying to access to the database I have the permission using "[DB].[dbo].[New_Table]"
. The dbWriteTable
function understand this parameter just as a pure name for the table, so I had to find a way to specify the right path to the database.
I did not find the way to do it using code directly. Solution: I went to the "ODBC Data Sources (32-bit)"
(Windows APP); and changed the configuration of my connection. The connection I had, was taking the master as the default database. I changed it for the database I have the permission. So now I'm using the following code to push the table from R-notebooks:
```{r}
dbWriteTable(con, "[R_Test2]", Data, overwrite = T)```
It's working perfectly for what I need.
If someone know how to specify this path using code, will be good to know. Maybe in the first configuration chunk:
```{r setup, include=FALSE}
library(odbc)
library(DBI)
con <- dbConnect(odbc::odbc(), "Enterprise", timeout = 10)```
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Regressionist |