Я сталкивался с этой проблемой слишком много раз, чтобы не попытаться написать свой собственный обходной путь. Лично я столкнулся с той же проблемой с Microsoft SQL Server, но решил, что это же решение будет работать и для SQLite. Я работаю с:
- База данных: Microsoft SQL Server, размещенный в Azure.
- R: 3.5.0
- ДБИ: 1.0.0
- одбк: 1.1.6
- ОС: Убунту 18.04
Подход:
Я хотел избежать зацикливания строк ради эффективности. Я обнаружил, что mapply
и paste0
можно комбинировать в более ориентированной на столбцы манере.
Я признаю, что это немного хакерски, но это хорошо работает для меня. Используйте на свой страх и риск; Я использую это только для небольшого побочного проекта, а не для корпоративного решения. В любом случае эффективность не должна быть такой большой проблемой, поскольку существует ограничение в 1000 строк в любом случае.
Замена для sqlAppendTable:
db_sql_append_table <- function(p_df, p_tbl) {
# p_df: data.frame that contains the data to append/insert into the table
# the names must be the same as those in the database
# p_tbl: the name of the database table to insert/append into
num_rows <- nrow(p_df)
num_cols <- ncol(p_df)
requires_quotes <- sapply(p_df, class) %in% c("character", "factor", "Date")
commas <- rep(", ", num_rows)
quotes <- rep("'", num_rows)
str_columns <- ' ('
column_names <- names(p_df)
for(i in 1:num_cols) {
if(i < num_cols) {
str_columns <- paste0(str_columns, column_names[i], ", ")
} else {
str_columns <- paste0(str_columns, column_names[i], ") ")
}
}
str_query <- paste0("INSERT INTO ", p_tbl, str_columns, "\nVALUES\n")
str_values <- rep("(", num_rows)
for(i in 1:num_cols) {
# not the last column; follow up with a comma
if(i < num_cols) {
if(requires_quotes[i]) {
str_values <- mapply(paste0, str_values, quotes, p_df[[column_names[i]]], quotes, commas)
} else {
str_values <- mapply(paste0, str_values, p_df[[column_names[i]]], commas)
}
# this is the last column; follow up with closing parenthesis
} else {
if(requires_quotes[i]) {
str_values <- mapply(paste0, str_values, quotes, p_df[[column_names[i]]], quotes, ")")
} else {
str_values <- mapply(paste0, str_values, p_df[[column_names[i]]], ")")
}
}
}
# build out the query; collapse values with comma & newline; end with semicolon;
str_values <- paste0(str_values, collapse=",\n")
str_query <- paste0(str_query, str_values)
str_query <- paste0(str_query, ";")
return(str_query)
}
Вызов функции:
Я хотел, чтобы это было максимально похоже на исходную функцию sqlAppendTable
. Эта функция только создает запрос.
Вам все еще нужно обернуть эту функцию вызовом dbExecute()
, чтобы фактически вставлять/добавлять строки в базу данных.
dbExecute(conn=conn, statement = db_sql_append_table(my_dataframe, "table_name"))
РЕДАКТИРОВАТЬ
- Добавлена дата как один из типов, которые также должны быть заключены в кавычки этой функцией. Спасибо за этот комментарий!
person
TaylorV
schedule
26.08.2018
dbWriteTable
RSQLite, указав аргумент append? - person Parfait   schedule 01.04.2017dbWriteTable
. - person Parfait   schedule 03.04.2017