Reputation: 2773
I need to create a table with table name having some special characters. I am using RSQLite
package. Table name I need to create is port.3.1
. It is not possible to create a table with this name. So I changed the table name to [port.3.1]
based on What are valid table names in SQLite?.
Now I can create the table, but I can't insert a dataframe to that table. The code I used is as follows:
createTable <- function(tableName){
c <- c(portDate='varchar(20) not null' ,
ticker='varchar(20)',
quantities='double(20,10)')
lite <- dbDriver("SQLite", max.con = 25)
db <- dbConnect(lite, dbname="sql.db")
if( length(which(strsplit(toString(tableName),'')[[1]]=='.') ) != 0){ tableName = paste("[",tableName,"]",sep="") } #check whether the portfolio contains special characters or not
sql <- dbBuildTableDefinition(db, tableName, NULL, field.types = c, row.names = FALSE)
print(sql)
dbGetQuery(db, sql)
}
datedPf <- data.frame(date=c("2001-01-01","2001-01-01"), ticker=c("a","b"),quantity=c(12,13))
for(port in c("port1","port2","port.3.1")){
createTable(port)
lite <- dbDriver("SQLite", max.con = 25)
db <- dbConnect(lite, dbname="sql.db")
if( length(which(strsplit(toString(port),'')[[1]]=='.') ) != 0){ port = paste("[",port,"]",sep="") } #check whether the portfolio contains special characters or not
dbWriteTable(db,port,datedPf ,append=TRUE,row.names=FALSE)
}
In this example, I can insert data frame to table port1
and port2
, but it is not inserting on tables [port.3.1]
. What is the reason behind this? How can I solve this problem?
Upvotes: 2
Views: 634
Reputation: 60858
Have a look at the sqliteWriteTable
implementation, simply by entering that name and pressing enter. You will notice two things:
[…]
foundTable <- dbExistsTable(con, name)
new.table <- !foundTable
createTable <- (new.table || foundTable && overwrite)
[…]
if (createTable) {
[…]
And looking at showMethods("dbExistsTable", includeDefs=T)
output you'll see that it uses dbListTables(conn)
which will return the unquoted version of your table name. So if you pass the quoted table name to sqliteWriteTable
, then it will incorrectly assume that your table does not exist, try to create it and then encounter an error. If you pass the unquoted table name, the creation statement will be wrong.
I'd consider this a bug in RSQLite. In my opinion, SQL statements the user passes have to be correctly quoted, but everywhere you pass a table name as a separate argument to a function, that table name should be unquoted by default and should get quoted in the SQL statements generated from it. It would be even better if the name were allowed in either quoted or unquoted form, but that's mainly to maximize portability. If you feel like it, you can try contact the developers to report this issue.
You can work around the problem:
setMethod(dbExistsTable, signature(conn="SQLiteConnection", name="character"),
function(conn, name, ...) {
lst <- dbListTables(conn)
lst <- c(lst, paste("[", lst, "]", sep=""))
match(tolower(name), tolower(lst), nomatch = 0) > 0
}
)
This will overwrite the default implementation of dbExistsTable
for SQLite connections with a version which checks for both quoted and unquoted table names. After this change, passing "[port.3.1]"
as the table name will cause foundTable
to be true, so RSQLite won't attempt to create that table for you.
Upvotes: 3