在R中用dbplyr向SQLite数据库追加tibble行时遇auto_copy错误
问题
我正在R中对文件路径列表循环应用函数,目标是借助dbplyr将输出追加到内存外的SQLite数据库中,该数据库当前为空且有预定义结构。
数据库结构如下:
database # Source: table<epi_table> [0 x 14] # Database: sqlite 3.44.2 [/home/me/repositories/some_path/data/some_path.db] # ℹ 14 variables: doc_index <int>, content_type <chr>, style_name <chr>, text <chr>, level <dbl>, # num_id <int>, row_id <int>, is_header <int>, cell_id <dbl>, col_span <dbl>, row_span <int>, # successful_import <int>, filepath <chr>, doc_vs_docx <chr>
每次循环的函数输出示例如下:
new_row <- structure(list(doc_index = 1L, content_type = "paragraph", style_name = NA_character_, text = "Some_text", level = NA_real_, num_id = NA_integer_, row_id = NA_integer_, is_header = NA, cell_id = NA_real_, col_span = NA_real_, row_span = NA_integer_, successful_import = TRUE, filepath = "some_file.docx", doc_vs_docx = "docx"), row.names = c(NA, -1L), class = c("tbl_df", "tbl", "data.frame")) new_row # A tibble: 1 × 14 doc_index content_type style_name text level num_id row_id is_header cell_id col_span row_span successful_import filepath doc_vs_docx <int> <chr> <chr> <chr> <dbl> <int> <int> <lgl> <dbl> <dbl> <int> <lgl> <chr> <chr> 1 1 paragraph NA Some_text NA NA NA NA NA NA NA TRUE some_file.docx docx
我尝试用以下代码插入行:
database |> rows_insert(new_rows, conflict = 'ignore')
但遇到了对象类不匹配的错误:
Error in `auto_copy()`: ! `x` and `y` must share the same src. ℹ `x` is a <tbl_SQLiteConnection/tbl_dbi/tbl_sql/tbl_lazy/tbl> object. ℹ `y` is a <tbl_df/tbl/data.frame> object. ℹ Set `copy = TRUE` if `y` can be copied to the same source as `x` (may be slow).
想知道:若要将常规tibble行添加到tbl对象,是否需要先转换?dbplyr是否不适用于该场景?目前不想学习标准SQL语法,一直依赖dbplyr。
解答
不需要额外转换tibble,dbplyr完全支持这个场景,只需在rows_insert中添加copy = TRUE参数即可解决类不匹配问题:
database |> rows_insert(new_rows, conflict = 'ignore', copy = TRUE)
额外注意事项
copy = TRUE会把本地内存中的tibble(new_rows)复制到数据库所在的数据源,让两者处于同一环境,dbplyr就能正常执行插入操作。单条或小批量数据插入时,性能影响可以忽略;如果是大规模数据,建议累积一定量后批量插入,能提升效率。- 注意字段类型匹配:数据库中
successful_import是<int>类型,但示例输出里该字段是<lgl>(布尔值)。虽然SQLite会自动转换,但为了严格匹配结构,可将输出中的successful_import转为整数(1代表TRUE,0代表FALSE),避免潜在问题。
内容的提问来源于stack exchange,提问作者GuedesBF
相关产品推荐
相关产品推荐

