Adding value to existing database table in RSQLite

Viewed 2531

I am new to RSQLite. I have an input document in text format in which values are seperately by '|' I created a table with the required variables (dummy code as follows)

db<-dbconnect(SQLite(),dbname="test.sqlite")

dbSendQuery(conn=db,
"CREATE TABLE TABLE1(
MARKS INTEGER,
ROLLNUM INTEGER
NAME CHAR(25)
DATED DATE)"
)

However I am struck at how to import values into the created table. I cannot use INSERT INTO Values command as there are thousands of rows and more than 20+ columns in the original data file and it is impossible to manually type in each data point.

Can someone suggest an alternative efficient way to do so?

3 Answers

You are using a scripting language. The deal of this is literally to avoid manually typing each data point. Sorry.

You have two routes:

1: You have corrected loaded a database connection and created an empty table in your SQLite database. Nice!

To load data into the table, load your text file into R using e.g. df <- read.table('textfile.txt', sep='|') (modify arguments to fit your text file).

To have a 'dynamic' INSERT statement, you can use placeholders. RSQLite allows for both named or positioned placeholder. To insert a single row, you can do:

dbSendQuery(db, 'INSERT INTO table1 (MARKS, ROLLNUM, NAME) VALUES (?, ?, ?);', list(1, 16, 'Big fellow'))

You see? The first ? got value 1, the second ? got value 16, and the last ? got the string Big fellow. Also note that you do not enclose placeholders for text in quotation marks (' or ")!

Now, you have thousands of rows. Or just more than one. Either way, you can send in your data frame. dbSendQuery has some requirements. 1) That each vector has the same number of entries (not an issue when providing a data.frame). And 2) You may only submit the same number of vectors as you have placeholders.

I assume your data frame, df contains columns mark, roll, and name, corrsponding to the columns. Then you may run:

dbSendQuery(db, 'INSERT INTO table1 (MARKS, ROLLNUM, NAME) VALUES (:mark, :roll, :name);', df)

This will execute an INSERT statement for each row in df!

TIP! Because an INSERT statement is execute for each row, inserting thousands of rows can take a long time, because after each insert, data is written to file and indices are updated. Insert, enclose it in an transaction:

dbBegin(db)
res <- dbSendQuery(db, 'INSERT ...;', df)
dbClearResult(res)
dbCommit(db)

and SQLite will save the data to a journal file, and only save the result when you execute the dbCommit(db). Try both methods and compare the speed!


2: Ah, yes. The second way. This can be done in SQLite entirely. With the SQLite command utility (sqlite3 from your command line, not R), you can attach a text file as a table and simply do a INSERT INTO ... SELECT ... ; command. Alternately, read the text file in sqlite3 into a temporary table and run a INSERT INTO ... SELECT ... ;.


Useful site to remember: http://www.sqlite.com/lang.html

A little late to the party, but DBI provides dbAppendTable() which will write the contents of a dataframe to an SQL table. Column names in the dataframe must match the field names in the database. For your example, the following code would insert the contents of my random dataframe into your newly created table.

library(DBI)

db<-dbConnect(RSQLite::SQLite(),dbname=":memory")

dbExecute(db,
          "CREATE TABLE TABLE1(
             MARKS INTEGER,
             ROLLNUM INTEGER,
             NAME TEXT
           )"
)

df <- data.frame(MARKS = sample(1:100, 10), 
                 ROLLNUM = sample(1:100, 10), 
                 NAME = stringi::stri_rand_strings(10, 10))

dbAppendTable(db, "TABLE1", df)

I don't think there is a nice way to do a large number of inserts directly from R. SQLite does have a bulk insert functionality, but the RSQLite package does not appear to expose it.

From the command line you may try the following:

.separator |
.import your_file.csv your_table

where your_file.csv is the CSV (or pipe delimited) file containing your data and your_table is the destination table.

See the documentation under CSV Import for more information.

Related